mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Merge pull request #46816 from dashpole/update_godep
Automatic merge from submit-queue (batch tested with PRs 46550, 46663, 46816, 46820, 46460) Update cAdvisor version to v0.26.0 issue: #46658 I have requested a 1 day exception for code freeze. /assign @dchen1107 ```release-note Fix disk partition discovery for brtfs Add ZFS support Add overlay2 storage driver support ```
This commit is contained in:
		
							
								
								
									
										187
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										187
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							@@ -1241,208 +1241,208 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/api",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/cache/memory",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/client/v2",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/collector",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/container",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/container/common",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/container/docker",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/container/libcontainer",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/container/raw",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/container/rkt",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/container/systemd",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/devicemapper",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/events",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/fs",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/healthz",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/http",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/http/mux",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/info/v1",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/info/v2",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/machine",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/manager",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/manager/watcher",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/manager/watcher/raw",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/manager/watcher/rkt",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/metrics",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/pages",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/pages/static",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/storage",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/summary",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/utils",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/utils/cloudinfo",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/utils/cpuload",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/utils/cpuload/netlink",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/utils/docker",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/utils/oomparser",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/utils/sysfs",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/utils/sysinfo",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/utils/tail",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/validate",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/version",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/cadvisor/zfs",
 | 
			
		||||
			"Comment": "v0.25.0-14-g2ddeb5f",
 | 
			
		||||
			"Rev": "2ddeb5f60e22d86c8d1eeb654dfb8bfadf93374c"
 | 
			
		||||
			"Comment": "v0.26.0-2-gb971fd1",
 | 
			
		||||
			"Rev": "b971fd1850f59f3e6e67842789217d9b006d6440"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/google/certificate-transparency/go",
 | 
			
		||||
@@ -2184,8 +2184,13 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/client_golang/prometheus",
 | 
			
		||||
			"Comment": "0.7.0-52-ge51041b",
 | 
			
		||||
			"Rev": "e51041b3fa41cece0dca035740ba6411905be473"
 | 
			
		||||
			"Comment": "v0.8.0-83-ge7e9030",
 | 
			
		||||
			"Rev": "e7e903064f5e9eb5da98208bae10b475d4db0f8c"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/client_golang/prometheus/promhttp",
 | 
			
		||||
			"Comment": "v0.8.0-83-ge7e9030",
 | 
			
		||||
			"Rev": "e7e903064f5e9eb5da98208bae10b475d4db0f8c"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/client_model/go",
 | 
			
		||||
@@ -2194,15 +2199,23 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/expfmt",
 | 
			
		||||
			"Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650"
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/model",
 | 
			
		||||
			"Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650"
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/procfs",
 | 
			
		||||
			"Rev": "454a56f35412459b5e684fd5ec0f9211b94f002a"
 | 
			
		||||
			"Rev": "65c1f6f8f0fc1e2185eb9863a3bc751496404259"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/procfs/xfs",
 | 
			
		||||
			"Rev": "65c1f6f8f0fc1e2185eb9863a3bc751496404259"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/quobyte/api",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										627
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										627
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							@@ -69290,6 +69290,215 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/prometheus/client_golang/prometheus/promhttp licensed under: =
 | 
			
		||||
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
 | 
			
		||||
= vendor/github.com/prometheus/client_golang/LICENSE 86d3f3a95c324c9479bd8986968f4327  -
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/prometheus/client_model/go licensed under: =
 | 
			
		||||
 | 
			
		||||
@@ -69708,6 +69917,215 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg licensed under: =
 | 
			
		||||
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
 | 
			
		||||
= vendor/github.com/prometheus/common/LICENSE 86d3f3a95c324c9479bd8986968f4327  -
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/prometheus/common/model licensed under: =
 | 
			
		||||
 | 
			
		||||
@@ -70126,6 +70544,215 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/prometheus/procfs/xfs licensed under: =
 | 
			
		||||
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
 | 
			
		||||
= vendor/github.com/prometheus/procfs/LICENSE 86d3f3a95c324c9479bd8986968f4327  -
 | 
			
		||||
================================================================================
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
================================================================================
 | 
			
		||||
= vendor/github.com/PuerkitoBio/purell licensed under: =
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								staging/src/k8s.io/apiserver/Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										16
									
								
								staging/src/k8s.io/apiserver/Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							@@ -520,7 +520,7 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/client_golang/prometheus",
 | 
			
		||||
			"Rev": "e51041b3fa41cece0dca035740ba6411905be473"
 | 
			
		||||
			"Rev": "e7e903064f5e9eb5da98208bae10b475d4db0f8c"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/client_model/go",
 | 
			
		||||
@@ -528,15 +528,23 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/expfmt",
 | 
			
		||||
			"Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650"
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/model",
 | 
			
		||||
			"Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650"
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/procfs",
 | 
			
		||||
			"Rev": "454a56f35412459b5e684fd5ec0f9211b94f002a"
 | 
			
		||||
			"Rev": "65c1f6f8f0fc1e2185eb9863a3bc751496404259"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/procfs/xfs",
 | 
			
		||||
			"Rev": "65c1f6f8f0fc1e2185eb9863a3bc751496404259"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/spf13/pflag",
 | 
			
		||||
 
 | 
			
		||||
@@ -24,26 +24,23 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	cacheHitCounter = prometheus.NewCounter(
 | 
			
		||||
		prometheus.CounterOpts{
 | 
			
		||||
			Name: "etcd_helper_cache_hit_count",
 | 
			
		||||
			Help: "Counter of etcd helper cache hits.",
 | 
			
		||||
		},
 | 
			
		||||
	)
 | 
			
		||||
	cacheMissCounter = prometheus.NewCounter(
 | 
			
		||||
		prometheus.CounterOpts{
 | 
			
		||||
			Name: "etcd_helper_cache_miss_count",
 | 
			
		||||
			Help: "Counter of etcd helper cache miss.",
 | 
			
		||||
		},
 | 
			
		||||
	)
 | 
			
		||||
	cacheEntryCounter = prometheus.NewCounter(
 | 
			
		||||
		prometheus.CounterOpts{
 | 
			
		||||
			Name: "etcd_helper_cache_entry_count",
 | 
			
		||||
			Help: "Counter of etcd helper cache entries. This can be different from etcd_helper_cache_miss_count " +
 | 
			
		||||
				"because two concurrent threads can miss the cache and generate the same entry twice.",
 | 
			
		||||
		},
 | 
			
		||||
	)
 | 
			
		||||
	cacheGetLatency = prometheus.NewSummary(
 | 
			
		||||
	cacheHitCounterOpts = prometheus.CounterOpts{
 | 
			
		||||
		Name: "etcd_helper_cache_hit_count",
 | 
			
		||||
		Help: "Counter of etcd helper cache hits.",
 | 
			
		||||
	}
 | 
			
		||||
	cacheHitCounter      = prometheus.NewCounter(cacheHitCounterOpts)
 | 
			
		||||
	cacheMissCounterOpts = prometheus.CounterOpts{
 | 
			
		||||
		Name: "etcd_helper_cache_miss_count",
 | 
			
		||||
		Help: "Counter of etcd helper cache miss.",
 | 
			
		||||
	}
 | 
			
		||||
	cacheMissCounter      = prometheus.NewCounter(cacheMissCounterOpts)
 | 
			
		||||
	cacheEntryCounterOpts = prometheus.CounterOpts{
 | 
			
		||||
		Name: "etcd_helper_cache_entry_count",
 | 
			
		||||
		Help: "Counter of etcd helper cache entries. This can be different from etcd_helper_cache_miss_count " +
 | 
			
		||||
			"because two concurrent threads can miss the cache and generate the same entry twice.",
 | 
			
		||||
	}
 | 
			
		||||
	cacheEntryCounter = prometheus.NewCounter(cacheEntryCounterOpts)
 | 
			
		||||
	cacheGetLatency   = prometheus.NewSummary(
 | 
			
		||||
		prometheus.SummaryOpts{
 | 
			
		||||
			Name: "etcd_request_cache_get_latencies_summary",
 | 
			
		||||
			Help: "Latency in microseconds of getting an object from etcd cache",
 | 
			
		||||
@@ -104,9 +101,9 @@ func ObserveNewEntry() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Reset() {
 | 
			
		||||
	cacheHitCounter.Set(0)
 | 
			
		||||
	cacheMissCounter.Set(0)
 | 
			
		||||
	cacheEntryCounter.Set(0)
 | 
			
		||||
	cacheHitCounter = prometheus.NewCounter(cacheHitCounterOpts)
 | 
			
		||||
	cacheMissCounter = prometheus.NewCounter(cacheMissCounterOpts)
 | 
			
		||||
	cacheEntryCounter = prometheus.NewCounter(cacheEntryCounterOpts)
 | 
			
		||||
	// TODO: Reset cacheAddLatency.
 | 
			
		||||
	// TODO: Reset cacheGetLatency.
 | 
			
		||||
	etcdRequestLatenciesSummary.Reset()
 | 
			
		||||
 
 | 
			
		||||
@@ -268,7 +268,7 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/client_golang/prometheus",
 | 
			
		||||
			"Rev": "e51041b3fa41cece0dca035740ba6411905be473"
 | 
			
		||||
			"Rev": "e7e903064f5e9eb5da98208bae10b475d4db0f8c"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/client_model/go",
 | 
			
		||||
@@ -276,15 +276,23 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/expfmt",
 | 
			
		||||
			"Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650"
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/model",
 | 
			
		||||
			"Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650"
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/procfs",
 | 
			
		||||
			"Rev": "454a56f35412459b5e684fd5ec0f9211b94f002a"
 | 
			
		||||
			"Rev": "65c1f6f8f0fc1e2185eb9863a3bc751496404259"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/procfs/xfs",
 | 
			
		||||
			"Rev": "65c1f6f8f0fc1e2185eb9863a3bc751496404259"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/spf13/cobra",
 | 
			
		||||
 
 | 
			
		||||
@@ -260,7 +260,7 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/client_golang/prometheus",
 | 
			
		||||
			"Rev": "e51041b3fa41cece0dca035740ba6411905be473"
 | 
			
		||||
			"Rev": "e7e903064f5e9eb5da98208bae10b475d4db0f8c"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/client_model/go",
 | 
			
		||||
@@ -268,15 +268,23 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/expfmt",
 | 
			
		||||
			"Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650"
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/model",
 | 
			
		||||
			"Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650"
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/procfs",
 | 
			
		||||
			"Rev": "454a56f35412459b5e684fd5ec0f9211b94f002a"
 | 
			
		||||
			"Rev": "65c1f6f8f0fc1e2185eb9863a3bc751496404259"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/procfs/xfs",
 | 
			
		||||
			"Rev": "65c1f6f8f0fc1e2185eb9863a3bc751496404259"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/spf13/cobra",
 | 
			
		||||
 
 | 
			
		||||
@@ -256,7 +256,7 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/client_golang/prometheus",
 | 
			
		||||
			"Rev": "e51041b3fa41cece0dca035740ba6411905be473"
 | 
			
		||||
			"Rev": "e7e903064f5e9eb5da98208bae10b475d4db0f8c"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/client_model/go",
 | 
			
		||||
@@ -264,15 +264,23 @@
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/expfmt",
 | 
			
		||||
			"Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650"
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg",
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/common/model",
 | 
			
		||||
			"Rev": "ffe929a3f4c4faeaa10f2b9535c2b1be3ad15650"
 | 
			
		||||
			"Rev": "13ba4ddd0caa9c28ca7b7bffe1dfa9ed8d5ef207"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/procfs",
 | 
			
		||||
			"Rev": "454a56f35412459b5e684fd5ec0f9211b94f002a"
 | 
			
		||||
			"Rev": "65c1f6f8f0fc1e2185eb9863a3bc751496404259"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/prometheus/procfs/xfs",
 | 
			
		||||
			"Rev": "65c1f6f8f0fc1e2185eb9863a3bc751496404259"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"ImportPath": "github.com/spf13/cobra",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/BUILD
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/BUILD
									
									
									
									
										vendored
									
									
								
							@@ -281,6 +281,7 @@ filegroup(
 | 
			
		||||
        "//vendor/github.com/prometheus/client_golang/prometheus:all-srcs",
 | 
			
		||||
        "//vendor/github.com/prometheus/client_model/go:all-srcs",
 | 
			
		||||
        "//vendor/github.com/prometheus/common/expfmt:all-srcs",
 | 
			
		||||
        "//vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg:all-srcs",
 | 
			
		||||
        "//vendor/github.com/prometheus/common/model:all-srcs",
 | 
			
		||||
        "//vendor/github.com/prometheus/procfs:all-srcs",
 | 
			
		||||
        "//vendor/github.com/quobyte/api:all-srcs",
 | 
			
		||||
@@ -348,7 +349,6 @@ filegroup(
 | 
			
		||||
        "//vendor/golang.org/x/time/rate:all-srcs",
 | 
			
		||||
        "//vendor/golang.org/x/tools/container/intsets:all-srcs",
 | 
			
		||||
        "//vendor/google.golang.org/api/cloudmonitoring/v2beta2:all-srcs",
 | 
			
		||||
        "//vendor/google.golang.org/api/compute/v0.alpha:all-srcs",
 | 
			
		||||
        "//vendor/google.golang.org/api/compute/v0.beta:all-srcs",
 | 
			
		||||
        "//vendor/google.golang.org/api/compute/v1:all-srcs",
 | 
			
		||||
        "//vendor/google.golang.org/api/container/v1:all-srcs",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										68
									
								
								vendor/github.com/google/cadvisor/container/common/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										68
									
								
								vendor/github.com/google/cadvisor/container/common/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -223,3 +223,71 @@ func ListContainers(name string, cgroupPaths map[string]string, listType contain
 | 
			
		||||
 | 
			
		||||
	return ret, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AssignDeviceNamesToDiskStats assigns the Device field on the provided DiskIoStats by looking up
 | 
			
		||||
// the device major and minor identifiers in the provided device namer.
 | 
			
		||||
func AssignDeviceNamesToDiskStats(namer DeviceNamer, stats *info.DiskIoStats) {
 | 
			
		||||
	assignDeviceNamesToPerDiskStats(
 | 
			
		||||
		namer,
 | 
			
		||||
		stats.IoMerged,
 | 
			
		||||
		stats.IoQueued,
 | 
			
		||||
		stats.IoServiceBytes,
 | 
			
		||||
		stats.IoServiceTime,
 | 
			
		||||
		stats.IoServiced,
 | 
			
		||||
		stats.IoTime,
 | 
			
		||||
		stats.IoWaitTime,
 | 
			
		||||
		stats.Sectors,
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// assignDeviceNamesToPerDiskStats looks up device names for the provided stats, caching names
 | 
			
		||||
// if necessary.
 | 
			
		||||
func assignDeviceNamesToPerDiskStats(namer DeviceNamer, diskStats ...[]info.PerDiskStats) {
 | 
			
		||||
	devices := make(deviceIdentifierMap)
 | 
			
		||||
	for _, stats := range diskStats {
 | 
			
		||||
		for i, stat := range stats {
 | 
			
		||||
			stats[i].Device = devices.Find(stat.Major, stat.Minor, namer)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeviceNamer returns string names for devices by their major and minor id.
 | 
			
		||||
type DeviceNamer interface {
 | 
			
		||||
	// DeviceName returns the name of the device by its major and minor ids, or false if no
 | 
			
		||||
	// such device is recognized.
 | 
			
		||||
	DeviceName(major, minor uint64) (string, bool)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type MachineInfoNamer info.MachineInfo
 | 
			
		||||
 | 
			
		||||
func (n *MachineInfoNamer) DeviceName(major, minor uint64) (string, bool) {
 | 
			
		||||
	for _, info := range n.DiskMap {
 | 
			
		||||
		if info.Major == major && info.Minor == minor {
 | 
			
		||||
			return "/dev/" + info.Name, true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for _, info := range n.Filesystems {
 | 
			
		||||
		if info.DeviceMajor == major && info.DeviceMinor == minor {
 | 
			
		||||
			return info.Device, true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return "", false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type deviceIdentifier struct {
 | 
			
		||||
	major uint64
 | 
			
		||||
	minor uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type deviceIdentifierMap map[deviceIdentifier]string
 | 
			
		||||
 | 
			
		||||
// Find locates the device name by device identifier out of from, caching the result as necessary.
 | 
			
		||||
func (m deviceIdentifierMap) Find(major, minor uint64, namer DeviceNamer) string {
 | 
			
		||||
	d := deviceIdentifier{major, minor}
 | 
			
		||||
	if s, ok := m[d]; ok {
 | 
			
		||||
		return s
 | 
			
		||||
	}
 | 
			
		||||
	s, _ := namer.DeviceName(major, minor)
 | 
			
		||||
	m[d] = s
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/github.com/google/cadvisor/container/docker/docker.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/google/cadvisor/container/docker/docker.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -37,7 +37,10 @@ func Status() (v1.DockerStatus, error) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return v1.DockerStatus{}, err
 | 
			
		||||
	}
 | 
			
		||||
	return StatusFromDockerInfo(dockerInfo), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func StatusFromDockerInfo(dockerInfo dockertypes.Info) v1.DockerStatus {
 | 
			
		||||
	out := v1.DockerStatus{}
 | 
			
		||||
	out.Version = VersionString()
 | 
			
		||||
	out.APIVersion = APIVersionString()
 | 
			
		||||
@@ -53,7 +56,7 @@ func Status() (v1.DockerStatus, error) {
 | 
			
		||||
	for _, v := range dockerInfo.DriverStatus {
 | 
			
		||||
		out.DriverStatus[v[0]] = v[1]
 | 
			
		||||
	}
 | 
			
		||||
	return out, nil
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Images() ([]v1.DockerImage, error) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/github.com/google/cadvisor/container/docker/factory.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/google/cadvisor/container/docker/factory.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -84,6 +84,7 @@ const (
 | 
			
		||||
	devicemapperStorageDriver storageDriver = "devicemapper"
 | 
			
		||||
	aufsStorageDriver         storageDriver = "aufs"
 | 
			
		||||
	overlayStorageDriver      storageDriver = "overlay"
 | 
			
		||||
	overlay2StorageDriver     storageDriver = "overlay2"
 | 
			
		||||
	zfsStorageDriver          storageDriver = "zfs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -107,6 +108,7 @@ type dockerFactory struct {
 | 
			
		||||
 | 
			
		||||
	ignoreMetrics container.MetricSet
 | 
			
		||||
 | 
			
		||||
	thinPoolName    string
 | 
			
		||||
	thinPoolWatcher *devicemapper.ThinPoolWatcher
 | 
			
		||||
 | 
			
		||||
	zfsWatcher *zfs.ZfsWatcher
 | 
			
		||||
@@ -136,6 +138,7 @@ func (self *dockerFactory) NewContainerHandler(name string, inHostNamespace bool
 | 
			
		||||
		metadataEnvs,
 | 
			
		||||
		self.dockerVersion,
 | 
			
		||||
		self.ignoreMetrics,
 | 
			
		||||
		self.thinPoolName,
 | 
			
		||||
		self.thinPoolWatcher,
 | 
			
		||||
		self.zfsWatcher,
 | 
			
		||||
	)
 | 
			
		||||
@@ -323,12 +326,18 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics c
 | 
			
		||||
		return fmt.Errorf("failed to get cgroup subsystems: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var thinPoolWatcher *devicemapper.ThinPoolWatcher
 | 
			
		||||
	var (
 | 
			
		||||
		thinPoolWatcher *devicemapper.ThinPoolWatcher
 | 
			
		||||
		thinPoolName    string
 | 
			
		||||
	)
 | 
			
		||||
	if storageDriver(dockerInfo.Driver) == devicemapperStorageDriver {
 | 
			
		||||
		thinPoolWatcher, err = startThinPoolWatcher(dockerInfo)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			glog.Errorf("devicemapper filesystem stats will not be reported: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		status := StatusFromDockerInfo(*dockerInfo)
 | 
			
		||||
		thinPoolName = status.DriverStatus[dockerutil.DriverStatusPoolName]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var zfsWatcher *zfs.ZfsWatcher
 | 
			
		||||
@@ -350,6 +359,7 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics c
 | 
			
		||||
		storageDriver:      storageDriver(dockerInfo.Driver),
 | 
			
		||||
		storageDir:         RootDir(),
 | 
			
		||||
		ignoreMetrics:      ignoreMetrics,
 | 
			
		||||
		thinPoolName:       thinPoolName,
 | 
			
		||||
		thinPoolWatcher:    thinPoolWatcher,
 | 
			
		||||
		zfsWatcher:         zfsWatcher,
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								vendor/github.com/google/cadvisor/container/docker/handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/google/cadvisor/container/docker/handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -19,6 +19,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
@@ -112,6 +113,9 @@ type dockerContainerHandler struct {
 | 
			
		||||
 | 
			
		||||
	// zfs watcher
 | 
			
		||||
	zfsWatcher *zfs.ZfsWatcher
 | 
			
		||||
 | 
			
		||||
	// container restart count
 | 
			
		||||
	restartCount int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ container.ContainerHandler = &dockerContainerHandler{}
 | 
			
		||||
@@ -146,6 +150,7 @@ func newDockerContainerHandler(
 | 
			
		||||
	metadataEnvs []string,
 | 
			
		||||
	dockerVersion []int,
 | 
			
		||||
	ignoreMetrics container.MetricSet,
 | 
			
		||||
	thinPoolName string,
 | 
			
		||||
	thinPoolWatcher *devicemapper.ThinPoolWatcher,
 | 
			
		||||
	zfsWatcher *zfs.ZfsWatcher,
 | 
			
		||||
) (container.ContainerHandler, error) {
 | 
			
		||||
@@ -180,18 +185,18 @@ func newDockerContainerHandler(
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Determine the rootfs storage dir OR the pool name to determine the device
 | 
			
		||||
	// Determine the rootfs storage dir OR the pool name to determine the device.
 | 
			
		||||
	// For devicemapper, we only need the thin pool name, and that is passed in to this call
 | 
			
		||||
	var (
 | 
			
		||||
		rootfsStorageDir string
 | 
			
		||||
		poolName         string
 | 
			
		||||
		zfsFilesystem    string
 | 
			
		||||
		zfsParent        string
 | 
			
		||||
	)
 | 
			
		||||
	switch storageDriver {
 | 
			
		||||
	case aufsStorageDriver:
 | 
			
		||||
		rootfsStorageDir = path.Join(storageDir, string(aufsStorageDriver), aufsRWLayer, rwLayerID)
 | 
			
		||||
	case overlayStorageDriver:
 | 
			
		||||
		rootfsStorageDir = path.Join(storageDir, string(overlayStorageDriver), rwLayerID)
 | 
			
		||||
	case overlayStorageDriver, overlay2StorageDriver:
 | 
			
		||||
		rootfsStorageDir = path.Join(storageDir, string(storageDriver), rwLayerID)
 | 
			
		||||
	case zfsStorageDriver:
 | 
			
		||||
		status, err := Status()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
@@ -199,13 +204,6 @@ func newDockerContainerHandler(
 | 
			
		||||
		}
 | 
			
		||||
		zfsParent = status.DriverStatus[dockerutil.DriverStatusParentDataset]
 | 
			
		||||
		zfsFilesystem = path.Join(zfsParent, rwLayerID)
 | 
			
		||||
	case devicemapperStorageDriver:
 | 
			
		||||
		status, err := Status()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("unable to determine docker status: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		poolName = status.DriverStatus[dockerutil.DriverStatusPoolName]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// TODO: extract object mother method
 | 
			
		||||
@@ -219,7 +217,7 @@ func newDockerContainerHandler(
 | 
			
		||||
		storageDriver:      storageDriver,
 | 
			
		||||
		fsInfo:             fsInfo,
 | 
			
		||||
		rootFs:             rootFs,
 | 
			
		||||
		poolName:           poolName,
 | 
			
		||||
		poolName:           thinPoolName,
 | 
			
		||||
		zfsFilesystem:      zfsFilesystem,
 | 
			
		||||
		rootfsStorageDir:   rootfsStorageDir,
 | 
			
		||||
		envs:               make(map[string]string),
 | 
			
		||||
@@ -248,6 +246,7 @@ func newDockerContainerHandler(
 | 
			
		||||
	handler.image = ctnr.Config.Image
 | 
			
		||||
	handler.networkMode = ctnr.HostConfig.NetworkMode
 | 
			
		||||
	handler.deviceID = ctnr.GraphDriver.Data["DeviceId"]
 | 
			
		||||
	handler.restartCount = ctnr.RestartCount
 | 
			
		||||
 | 
			
		||||
	// Obtain the IP address for the contianer.
 | 
			
		||||
	// If the NetworkMode starts with 'container:' then we need to use the IP address of the container specified.
 | 
			
		||||
@@ -383,6 +382,10 @@ func (self *dockerContainerHandler) GetSpec() (info.ContainerSpec, error) {
 | 
			
		||||
	spec, err := common.GetSpec(self.cgroupPaths, self.machineInfoFactory, self.needNet(), hasFilesystem)
 | 
			
		||||
 | 
			
		||||
	spec.Labels = self.labels
 | 
			
		||||
	// Only adds restartcount label if it's greater than 0
 | 
			
		||||
	if self.restartCount > 0 {
 | 
			
		||||
		spec.Labels["restartcount"] = strconv.Itoa(self.restartCount)
 | 
			
		||||
	}
 | 
			
		||||
	spec.Envs = self.envs
 | 
			
		||||
	spec.Image = self.image
 | 
			
		||||
 | 
			
		||||
@@ -390,6 +393,15 @@ func (self *dockerContainerHandler) GetSpec() (info.ContainerSpec, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error {
 | 
			
		||||
	mi, err := self.machineInfoFactory.GetMachineInfo()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !self.ignoreMetrics.Has(container.DiskIOMetrics) {
 | 
			
		||||
		common.AssignDeviceNamesToDiskStats((*common.MachineInfoNamer)(mi), &stats.DiskIo)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if self.ignoreMetrics.Has(container.DiskUsageMetrics) {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
@@ -399,7 +411,7 @@ func (self *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error
 | 
			
		||||
		// Device has to be the pool name to correlate with the device name as
 | 
			
		||||
		// set in the machine info filesystems.
 | 
			
		||||
		device = self.poolName
 | 
			
		||||
	case aufsStorageDriver, overlayStorageDriver:
 | 
			
		||||
	case aufsStorageDriver, overlayStorageDriver, overlay2StorageDriver:
 | 
			
		||||
		deviceInfo, err := self.fsInfo.GetDirFsDevice(self.rootfsStorageDir)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return fmt.Errorf("unable to determine device info for dir: %v: %v", self.rootfsStorageDir, err)
 | 
			
		||||
@@ -411,11 +423,6 @@ func (self *dockerContainerHandler) getFsStats(stats *info.ContainerStats) error
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mi, err := self.machineInfoFactory.GetMachineInfo()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		limit  uint64
 | 
			
		||||
		fsType string
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/google/cadvisor/container/factory.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/google/cadvisor/container/factory.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -48,6 +48,7 @@ const (
 | 
			
		||||
	DiskUsageMetrics       MetricKind = "disk"
 | 
			
		||||
	NetworkUsageMetrics    MetricKind = "network"
 | 
			
		||||
	NetworkTcpUsageMetrics MetricKind = "tcp"
 | 
			
		||||
	NetworkUdpUsageMetrics MetricKind = "udp"
 | 
			
		||||
	AppMetrics             MetricKind = "app"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										84
									
								
								vendor/github.com/google/cadvisor/container/libcontainer/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										84
									
								
								vendor/github.com/google/cadvisor/container/libcontainer/helpers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -17,6 +17,7 @@ package libcontainer
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
@@ -118,6 +119,21 @@ func GetStats(cgroupManager cgroups.Manager, rootFs string, pid int, ignoreMetri
 | 
			
		||||
			stats.Network.Tcp6 = t6
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if !ignoreMetrics.Has(container.NetworkUdpUsageMetrics) {
 | 
			
		||||
		u, err := udpStatsFromProc(rootFs, pid, "net/udp")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			glog.V(2).Infof("Unable to get udp stats from pid %d: %v", pid, err)
 | 
			
		||||
		} else {
 | 
			
		||||
			stats.Network.Udp = u
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		u6, err := udpStatsFromProc(rootFs, pid, "net/udp6")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			glog.V(2).Infof("Unable to get udp6 stats from pid %d: %v", pid, err)
 | 
			
		||||
		} else {
 | 
			
		||||
			stats.Network.Udp6 = u6
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// For backwards compatibility.
 | 
			
		||||
	if len(stats.Network.Interfaces) > 0 {
 | 
			
		||||
@@ -291,6 +307,74 @@ func scanTcpStats(tcpStatsFile string) (info.TcpStat, error) {
 | 
			
		||||
	return stats, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func udpStatsFromProc(rootFs string, pid int, file string) (info.UdpStat, error) {
 | 
			
		||||
	var err error
 | 
			
		||||
	var udpStats info.UdpStat
 | 
			
		||||
 | 
			
		||||
	udpStatsFile := path.Join(rootFs, "proc", strconv.Itoa(pid), file)
 | 
			
		||||
 | 
			
		||||
	r, err := os.Open(udpStatsFile)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return udpStats, fmt.Errorf("failure opening %s: %v", udpStatsFile, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	udpStats, err = scanUdpStats(r)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return udpStats, fmt.Errorf("couldn't read udp stats: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return udpStats, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func scanUdpStats(r io.Reader) (info.UdpStat, error) {
 | 
			
		||||
	var stats info.UdpStat
 | 
			
		||||
 | 
			
		||||
	scanner := bufio.NewScanner(r)
 | 
			
		||||
	scanner.Split(bufio.ScanLines)
 | 
			
		||||
 | 
			
		||||
	// Discard header line
 | 
			
		||||
	if b := scanner.Scan(); !b {
 | 
			
		||||
		return stats, scanner.Err()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	listening := uint64(0)
 | 
			
		||||
	dropped := uint64(0)
 | 
			
		||||
	rxQueued := uint64(0)
 | 
			
		||||
	txQueued := uint64(0)
 | 
			
		||||
 | 
			
		||||
	for scanner.Scan() {
 | 
			
		||||
		line := scanner.Text()
 | 
			
		||||
		// Format: sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt  uid timeout inode ref pointer drops
 | 
			
		||||
 | 
			
		||||
		listening++
 | 
			
		||||
 | 
			
		||||
		fs := strings.Fields(line)
 | 
			
		||||
		if len(fs) != 13 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		rx, tx := uint64(0), uint64(0)
 | 
			
		||||
		fmt.Sscanf(fs[4], "%X:%X", &rx, &tx)
 | 
			
		||||
		rxQueued += rx
 | 
			
		||||
		txQueued += tx
 | 
			
		||||
 | 
			
		||||
		d, err := strconv.Atoi(string(fs[12]))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		dropped += uint64(d)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stats = info.UdpStat{
 | 
			
		||||
		Listen:   listening,
 | 
			
		||||
		Dropped:  dropped,
 | 
			
		||||
		RxQueued: rxQueued,
 | 
			
		||||
		TxQueued: txQueued,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return stats, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetProcesses(cgroupManager cgroups.Manager) ([]int, error) {
 | 
			
		||||
	pids, err := cgroupManager.GetPids()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										27
									
								
								vendor/github.com/google/cadvisor/container/raw/handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/google/cadvisor/container/raw/handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -197,6 +197,7 @@ func fsToFsStats(fs *fs.Fs) info.FsStats {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
 | 
			
		||||
	var allFs []fs.Fs
 | 
			
		||||
	// Get Filesystem information only for the root cgroup.
 | 
			
		||||
	if isRootCgroup(self.name) {
 | 
			
		||||
		filesystems, err := self.fsInfo.GetGlobalFsInfo()
 | 
			
		||||
@@ -207,6 +208,7 @@ func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
 | 
			
		||||
			fs := filesystems[i]
 | 
			
		||||
			stats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs))
 | 
			
		||||
		}
 | 
			
		||||
		allFs = filesystems
 | 
			
		||||
	} else if len(self.externalMounts) > 0 {
 | 
			
		||||
		var mountSet map[string]struct{}
 | 
			
		||||
		mountSet = make(map[string]struct{})
 | 
			
		||||
@@ -221,7 +223,10 @@ func (self *rawContainerHandler) getFsStats(stats *info.ContainerStats) error {
 | 
			
		||||
			fs := filesystems[i]
 | 
			
		||||
			stats.Filesystem = append(stats.Filesystem, fsToFsStats(&fs))
 | 
			
		||||
		}
 | 
			
		||||
		allFs = filesystems
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	common.AssignDeviceNamesToDiskStats(&fsNamer{fs: allFs, factory: self.machineInfoFactory}, &stats.DiskIo)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -272,3 +277,25 @@ func (self *rawContainerHandler) Exists() bool {
 | 
			
		||||
func (self *rawContainerHandler) Type() container.ContainerType {
 | 
			
		||||
	return container.ContainerTypeRaw
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type fsNamer struct {
 | 
			
		||||
	fs      []fs.Fs
 | 
			
		||||
	factory info.MachineInfoFactory
 | 
			
		||||
	info    common.DeviceNamer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *fsNamer) DeviceName(major, minor uint64) (string, bool) {
 | 
			
		||||
	for _, info := range n.fs {
 | 
			
		||||
		if uint64(info.Major) == major && uint64(info.Minor) == minor {
 | 
			
		||||
			return info.Device, true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if n.info == nil {
 | 
			
		||||
		mi, err := n.factory.GetMachineInfo()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", false
 | 
			
		||||
		}
 | 
			
		||||
		n.info = (*common.MachineInfoNamer)(mi)
 | 
			
		||||
	}
 | 
			
		||||
	return n.info.DeviceName(major, minor)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								vendor/github.com/google/cadvisor/container/rkt/handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/google/cadvisor/container/rkt/handler.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -202,6 +202,15 @@ func (handler *rktContainerHandler) GetSpec() (info.ContainerSpec, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (handler *rktContainerHandler) getFsStats(stats *info.ContainerStats) error {
 | 
			
		||||
	mi, err := handler.machineInfoFactory.GetMachineInfo()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !handler.ignoreMetrics.Has(container.DiskIOMetrics) {
 | 
			
		||||
		common.AssignDeviceNamesToDiskStats((*common.MachineInfoNamer)(mi), &stats.DiskIo)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if handler.ignoreMetrics.Has(container.DiskUsageMetrics) {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
@@ -211,10 +220,6 @@ func (handler *rktContainerHandler) getFsStats(stats *info.ContainerStats) error
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mi, err := handler.machineInfoFactory.GetMachineInfo()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	var limit uint64 = 0
 | 
			
		||||
 | 
			
		||||
	// Use capacity as limit.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								vendor/github.com/google/cadvisor/fs/fs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/google/cadvisor/fs/fs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -266,7 +266,7 @@ func getDockerImagePaths(context Context) map[string]struct{} {
 | 
			
		||||
 | 
			
		||||
	// TODO(rjnagal): Detect docker root and graphdriver directories from docker info.
 | 
			
		||||
	dockerRoot := context.Docker.Root
 | 
			
		||||
	for _, dir := range []string{"devicemapper", "btrfs", "aufs", "overlay", "zfs"} {
 | 
			
		||||
	for _, dir := range []string{"devicemapper", "btrfs", "aufs", "overlay", "overlay2", "zfs"} {
 | 
			
		||||
		dockerImagePaths[path.Join(dockerRoot, dir)] = struct{}{}
 | 
			
		||||
	}
 | 
			
		||||
	for dockerRoot != "/" && dockerRoot != "." {
 | 
			
		||||
@@ -455,11 +455,15 @@ func (self *RealFsInfo) GetDirFsDevice(dir string) (*DeviceInfo, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *RealFsInfo) GetDirDiskUsage(dir string, timeout time.Duration) (uint64, error) {
 | 
			
		||||
	claimToken()
 | 
			
		||||
	defer releaseToken()
 | 
			
		||||
	return GetDirDiskUsage(dir, timeout)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetDirDiskUsage(dir string, timeout time.Duration) (uint64, error) {
 | 
			
		||||
	if dir == "" {
 | 
			
		||||
		return 0, fmt.Errorf("invalid directory")
 | 
			
		||||
	}
 | 
			
		||||
	claimToken()
 | 
			
		||||
	defer releaseToken()
 | 
			
		||||
	cmd := exec.Command("nice", "-n", "19", "du", "-s", dir)
 | 
			
		||||
	stdoutp, err := cmd.StdoutPipe()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -496,13 +500,17 @@ func (self *RealFsInfo) GetDirDiskUsage(dir string, timeout time.Duration) (uint
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (self *RealFsInfo) GetDirInodeUsage(dir string, timeout time.Duration) (uint64, error) {
 | 
			
		||||
	claimToken()
 | 
			
		||||
	defer releaseToken()
 | 
			
		||||
	return GetDirInodeUsage(dir, timeout)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetDirInodeUsage(dir string, timeout time.Duration) (uint64, error) {
 | 
			
		||||
	if dir == "" {
 | 
			
		||||
		return 0, fmt.Errorf("invalid directory")
 | 
			
		||||
	}
 | 
			
		||||
	var counter byteCounter
 | 
			
		||||
	var stderr bytes.Buffer
 | 
			
		||||
	claimToken()
 | 
			
		||||
	defer releaseToken()
 | 
			
		||||
	findCmd := exec.Command("find", dir, "-xdev", "-printf", ".")
 | 
			
		||||
	findCmd.Stdout, findCmd.Stderr = &counter, &stderr
 | 
			
		||||
	if err := findCmd.Start(); err != nil {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/google/cadvisor/http/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/google/cadvisor/http/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -23,6 +23,7 @@ go_library(
 | 
			
		||||
        "//vendor/github.com/google/cadvisor/pages/static:go_default_library",
 | 
			
		||||
        "//vendor/github.com/google/cadvisor/validate:go_default_library",
 | 
			
		||||
        "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
 | 
			
		||||
        "//vendor/github.com/prometheus/client_golang/prometheus/promhttp:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								vendor/github.com/google/cadvisor/http/handlers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/google/cadvisor/http/handlers.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -17,6 +17,7 @@ package http
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"github.com/google/cadvisor/api"
 | 
			
		||||
	"github.com/google/cadvisor/healthz"
 | 
			
		||||
@@ -30,6 +31,7 @@ import (
 | 
			
		||||
	auth "github.com/abbot/go-http-auth"
 | 
			
		||||
	"github.com/golang/glog"
 | 
			
		||||
	"github.com/prometheus/client_golang/prometheus"
 | 
			
		||||
	"github.com/prometheus/client_golang/prometheus/promhttp"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func RegisterHandlers(mux httpmux.Mux, containerManager manager.Manager, httpAuthFile, httpAuthRealm, httpDigestFile, httpDigestRealm string) error {
 | 
			
		||||
@@ -54,7 +56,7 @@ func RegisterHandlers(mux httpmux.Mux, containerManager manager.Manager, httpAut
 | 
			
		||||
	// Redirect / to containers page.
 | 
			
		||||
	mux.Handle("/", http.RedirectHandler(pages.ContainersPage, http.StatusTemporaryRedirect))
 | 
			
		||||
 | 
			
		||||
	var authenticated bool = false
 | 
			
		||||
	var authenticated bool
 | 
			
		||||
 | 
			
		||||
	// Setup the authenticator object
 | 
			
		||||
	if httpAuthFile != "" {
 | 
			
		||||
@@ -89,13 +91,16 @@ func RegisterHandlers(mux httpmux.Mux, containerManager manager.Manager, httpAut
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RegisterPrometheusHandler creates a new PrometheusCollector, registers it
 | 
			
		||||
// on the global registry and configures the provided HTTP mux to handle the
 | 
			
		||||
// given Prometheus endpoint.
 | 
			
		||||
// RegisterPrometheusHandler creates a new PrometheusCollector and configures
 | 
			
		||||
// the provided HTTP mux to handle the given Prometheus endpoint.
 | 
			
		||||
func RegisterPrometheusHandler(mux httpmux.Mux, containerManager manager.Manager, prometheusEndpoint string, f metrics.ContainerLabelsFunc) {
 | 
			
		||||
	collector := metrics.NewPrometheusCollector(containerManager, f)
 | 
			
		||||
	prometheus.MustRegister(collector)
 | 
			
		||||
	mux.Handle(prometheusEndpoint, prometheus.Handler())
 | 
			
		||||
	r := prometheus.NewRegistry()
 | 
			
		||||
	r.MustRegister(
 | 
			
		||||
		metrics.NewPrometheusCollector(containerManager, f),
 | 
			
		||||
		prometheus.NewGoCollector(),
 | 
			
		||||
		prometheus.NewProcessCollector(os.Getpid(), ""),
 | 
			
		||||
	)
 | 
			
		||||
	mux.Handle(prometheusEndpoint, promhttp.HandlerFor(r, promhttp.HandlerOpts{}))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func staticHandlerNoAuth(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								vendor/github.com/google/cadvisor/info/v1/container.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/google/cadvisor/info/v1/container.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -307,9 +307,10 @@ type CpuStats struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type PerDiskStats struct {
 | 
			
		||||
	Major uint64            `json:"major"`
 | 
			
		||||
	Minor uint64            `json:"minor"`
 | 
			
		||||
	Stats map[string]uint64 `json:"stats"`
 | 
			
		||||
	Device string            `json:"-"`
 | 
			
		||||
	Major  uint64            `json:"major"`
 | 
			
		||||
	Minor  uint64            `json:"minor"`
 | 
			
		||||
	Stats  map[string]uint64 `json:"stats"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type DiskIoStats struct {
 | 
			
		||||
@@ -386,6 +387,10 @@ type NetworkStats struct {
 | 
			
		||||
	Tcp TcpStat `json:"tcp"`
 | 
			
		||||
	// TCP6 connection stats (Established, Listen...)
 | 
			
		||||
	Tcp6 TcpStat `json:"tcp6"`
 | 
			
		||||
	// UDP connection stats
 | 
			
		||||
	Udp UdpStat `json:"udp"`
 | 
			
		||||
	// UDP6 connection stats
 | 
			
		||||
	Udp6 UdpStat `json:"udp6"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type TcpStat struct {
 | 
			
		||||
@@ -413,6 +418,20 @@ type TcpStat struct {
 | 
			
		||||
	Closing uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type UdpStat struct {
 | 
			
		||||
	// Count of UDP sockets in state "Listen"
 | 
			
		||||
	Listen uint64
 | 
			
		||||
 | 
			
		||||
	// Count of UDP packets dropped by the IP stack
 | 
			
		||||
	Dropped uint64
 | 
			
		||||
 | 
			
		||||
	// Count of packets Queued for Receieve
 | 
			
		||||
	RxQueued uint64
 | 
			
		||||
 | 
			
		||||
	// Count of packets Queued for Transmit
 | 
			
		||||
	TxQueued uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type FsStats struct {
 | 
			
		||||
	// The block device name associated with the filesystem.
 | 
			
		||||
	Device string `json:"device,omitempty"`
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/github.com/google/cadvisor/info/v1/machine.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/google/cadvisor/info/v1/machine.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -17,6 +17,10 @@ package v1
 | 
			
		||||
type FsInfo struct {
 | 
			
		||||
	// Block device associated with the filesystem.
 | 
			
		||||
	Device string `json:"device"`
 | 
			
		||||
	// DeviceMajor is the major identifier of the device, used for correlation with blkio stats
 | 
			
		||||
	DeviceMajor uint64 `json:"-"`
 | 
			
		||||
	// DeviceMinor is the minor identifier of the device, used for correlation with blkio stats
 | 
			
		||||
	DeviceMinor uint64 `json:"-"`
 | 
			
		||||
 | 
			
		||||
	// Total number of bytes available on the filesystem.
 | 
			
		||||
	Capacity uint64 `json:"capacity"`
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/github.com/google/cadvisor/info/v2/container.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/google/cadvisor/info/v2/container.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -269,6 +269,10 @@ type NetworkStats struct {
 | 
			
		||||
	Tcp TcpStat `json:"tcp"`
 | 
			
		||||
	// TCP6 connection stats (Established, Listen...)
 | 
			
		||||
	Tcp6 TcpStat `json:"tcp6"`
 | 
			
		||||
	// UDP connection stats
 | 
			
		||||
	Udp v1.UdpStat `json:"udp"`
 | 
			
		||||
	// UDP6 connection stats
 | 
			
		||||
	Udp6 v1.UdpStat `json:"udp6"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Instantaneous CPU stats
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/github.com/google/cadvisor/info/v2/conversion.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/google/cadvisor/info/v2/conversion.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -133,7 +133,7 @@ func ContainerStatsFromV1(containerName string, spec *v1.ContainerSpec, stats []
 | 
			
		||||
				}
 | 
			
		||||
			} else if len(val.Filesystem) > 1 && containerName != "/" {
 | 
			
		||||
				// Cannot handle multiple devices per container.
 | 
			
		||||
				glog.V(2).Infof("failed to handle multiple devices for container %s. Skipping Filesystem stats", containerName)
 | 
			
		||||
				glog.V(4).Infof("failed to handle multiple devices for container %s. Skipping Filesystem stats", containerName)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if spec.HasDiskIo {
 | 
			
		||||
@@ -259,6 +259,7 @@ func ContainerSpecFromV1(specV1 *v1.ContainerSpec, aliases []string, namespace s
 | 
			
		||||
		HasCustomMetrics: specV1.HasCustomMetrics,
 | 
			
		||||
		Image:            specV1.Image,
 | 
			
		||||
		Labels:           specV1.Labels,
 | 
			
		||||
		Envs:             specV1.Envs,
 | 
			
		||||
	}
 | 
			
		||||
	if specV1.HasCpu {
 | 
			
		||||
		specV2.Cpu.Limit = specV1.Cpu.Limit
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/github.com/google/cadvisor/machine/info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/google/cadvisor/machine/info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -116,7 +116,7 @@ func Info(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (*info.Mach
 | 
			
		||||
		if fs.Inodes != nil {
 | 
			
		||||
			inodes = *fs.Inodes
 | 
			
		||||
		}
 | 
			
		||||
		machineInfo.Filesystems = append(machineInfo.Filesystems, info.FsInfo{Device: fs.Device, Type: fs.Type.String(), Capacity: fs.Capacity, Inodes: inodes, HasInodes: fs.Inodes != nil})
 | 
			
		||||
		machineInfo.Filesystems = append(machineInfo.Filesystems, info.FsInfo{Device: fs.Device, DeviceMajor: uint64(fs.Major), DeviceMinor: uint64(fs.Minor), Type: fs.Type.String(), Capacity: fs.Capacity, Inodes: inodes, HasInodes: fs.Inodes != nil})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return machineInfo, nil
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								vendor/github.com/google/cadvisor/manager/manager.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/google/cadvisor/manager/manager.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -566,9 +566,24 @@ func (self *manager) getDockerContainer(containerName string) (*containerData, e
 | 
			
		||||
		Namespace: docker.DockerNamespace,
 | 
			
		||||
		Name:      containerName,
 | 
			
		||||
	}]
 | 
			
		||||
 | 
			
		||||
	// Look for container by short prefix name if no exact match found.
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, fmt.Errorf("unable to find Docker container %q", containerName)
 | 
			
		||||
		for contName, c := range self.containers {
 | 
			
		||||
			if contName.Namespace == docker.DockerNamespace && strings.HasPrefix(contName.Name, containerName) {
 | 
			
		||||
				if cont == nil {
 | 
			
		||||
					cont = c
 | 
			
		||||
				} else {
 | 
			
		||||
					return nil, fmt.Errorf("unable to find container. Container %q is not unique", containerName)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if cont == nil {
 | 
			
		||||
			return nil, fmt.Errorf("unable to find Docker container %q", containerName)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return cont, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										148
									
								
								vendor/github.com/google/cadvisor/metrics/prometheus.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										148
									
								
								vendor/github.com/google/cadvisor/metrics/prometheus.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -45,6 +45,14 @@ type metricValue struct {
 | 
			
		||||
 | 
			
		||||
type metricValues []metricValue
 | 
			
		||||
 | 
			
		||||
// asFloat64 converts a uint64 into a float64.
 | 
			
		||||
func asFloat64(v uint64) float64 { return float64(v) }
 | 
			
		||||
 | 
			
		||||
// asNanosecondsToSeconds converts nanoseconds into a float64 representing seconds.
 | 
			
		||||
func asNanosecondsToSeconds(v uint64) float64 {
 | 
			
		||||
	return float64(v) / float64(time.Second)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// fsValues is a helper method for assembling per-filesystem stats.
 | 
			
		||||
func fsValues(fsStats []info.FsStats, valueFn func(*info.FsStats) float64) metricValues {
 | 
			
		||||
	values := make(metricValues, 0, len(fsStats))
 | 
			
		||||
@@ -57,6 +65,24 @@ func fsValues(fsStats []info.FsStats, valueFn func(*info.FsStats) float64) metri
 | 
			
		||||
	return values
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ioValues is a helper method for assembling per-disk and per-filesystem stats.
 | 
			
		||||
func ioValues(ioStats []info.PerDiskStats, ioType string, ioValueFn func(uint64) float64, fsStats []info.FsStats, valueFn func(*info.FsStats) float64) metricValues {
 | 
			
		||||
	values := make(metricValues, 0, len(ioStats)+len(fsStats))
 | 
			
		||||
	for _, stat := range ioStats {
 | 
			
		||||
		values = append(values, metricValue{
 | 
			
		||||
			value:  ioValueFn(stat.Stats[ioType]),
 | 
			
		||||
			labels: []string{stat.Device},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	for _, stat := range fsStats {
 | 
			
		||||
		values = append(values, metricValue{
 | 
			
		||||
			value:  valueFn(&stat),
 | 
			
		||||
			labels: []string{stat.Device},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	return values
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// containerMetric describes a multi-dimensional metric used for exposing a
 | 
			
		||||
// certain type of container statistic.
 | 
			
		||||
type containerMetric struct {
 | 
			
		||||
@@ -130,10 +156,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					values := make(metricValues, 0, len(s.Cpu.Usage.PerCpu))
 | 
			
		||||
					for i, value := range s.Cpu.Usage.PerCpu {
 | 
			
		||||
						values = append(values, metricValue{
 | 
			
		||||
							value:  float64(value) / float64(time.Second),
 | 
			
		||||
							labels: []string{fmt.Sprintf("cpu%02d", i)},
 | 
			
		||||
						})
 | 
			
		||||
						if value > 0 {
 | 
			
		||||
							values = append(values, metricValue{
 | 
			
		||||
								value:  float64(value) / float64(time.Second),
 | 
			
		||||
								labels: []string{fmt.Sprintf("cpu%02d", i)},
 | 
			
		||||
							})
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					return values
 | 
			
		||||
				},
 | 
			
		||||
@@ -268,15 +296,29 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
 | 
			
		||||
						return float64(fs.Usage)
 | 
			
		||||
					})
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_reads_bytes_total",
 | 
			
		||||
				help:        "Cumulative count of bytes read",
 | 
			
		||||
				valueType:   prometheus.CounterValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.IoServiceBytes, "Read", asFloat64,
 | 
			
		||||
						nil, nil,
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_reads_total",
 | 
			
		||||
				help:        "Cumulative count of reads completed",
 | 
			
		||||
				valueType:   prometheus.CounterValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
						return float64(fs.ReadsCompleted)
 | 
			
		||||
					})
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.IoServiced, "Read", asFloat64,
 | 
			
		||||
						s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
							return float64(fs.ReadsCompleted)
 | 
			
		||||
						},
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_sector_reads_total",
 | 
			
		||||
@@ -284,9 +326,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
 | 
			
		||||
				valueType:   prometheus.CounterValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
						return float64(fs.SectorsRead)
 | 
			
		||||
					})
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.Sectors, "Read", asFloat64,
 | 
			
		||||
						s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
							return float64(fs.SectorsRead)
 | 
			
		||||
						},
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_reads_merged_total",
 | 
			
		||||
@@ -294,9 +339,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
 | 
			
		||||
				valueType:   prometheus.CounterValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
						return float64(fs.ReadsMerged)
 | 
			
		||||
					})
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.IoMerged, "Read", asFloat64,
 | 
			
		||||
						s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
							return float64(fs.ReadsMerged)
 | 
			
		||||
						},
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_read_seconds_total",
 | 
			
		||||
@@ -304,9 +352,23 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
 | 
			
		||||
				valueType:   prometheus.CounterValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
						return float64(fs.ReadTime) / float64(time.Second)
 | 
			
		||||
					})
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.IoServiceTime, "Read", asNanosecondsToSeconds,
 | 
			
		||||
						s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
							return float64(fs.ReadTime) / float64(time.Second)
 | 
			
		||||
						},
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_writes_bytes_total",
 | 
			
		||||
				help:        "Cumulative count of bytes written",
 | 
			
		||||
				valueType:   prometheus.CounterValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.IoServiceBytes, "Write", asFloat64,
 | 
			
		||||
						nil, nil,
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_writes_total",
 | 
			
		||||
@@ -314,9 +376,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
 | 
			
		||||
				valueType:   prometheus.CounterValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
						return float64(fs.WritesCompleted)
 | 
			
		||||
					})
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.IoServiced, "Write", asFloat64,
 | 
			
		||||
						s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
							return float64(fs.WritesCompleted)
 | 
			
		||||
						},
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_sector_writes_total",
 | 
			
		||||
@@ -324,9 +389,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
 | 
			
		||||
				valueType:   prometheus.CounterValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
						return float64(fs.SectorsWritten)
 | 
			
		||||
					})
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.Sectors, "Write", asFloat64,
 | 
			
		||||
						s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
							return float64(fs.SectorsWritten)
 | 
			
		||||
						},
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_writes_merged_total",
 | 
			
		||||
@@ -334,9 +402,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
 | 
			
		||||
				valueType:   prometheus.CounterValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
						return float64(fs.WritesMerged)
 | 
			
		||||
					})
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.IoMerged, "Write", asFloat64,
 | 
			
		||||
						s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
							return float64(fs.WritesMerged)
 | 
			
		||||
						},
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_write_seconds_total",
 | 
			
		||||
@@ -344,9 +415,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
 | 
			
		||||
				valueType:   prometheus.CounterValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
						return float64(fs.WriteTime) / float64(time.Second)
 | 
			
		||||
					})
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.IoServiceTime, "Write", asNanosecondsToSeconds,
 | 
			
		||||
						s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
							return float64(fs.WriteTime) / float64(time.Second)
 | 
			
		||||
						},
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_io_current",
 | 
			
		||||
@@ -354,9 +428,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
 | 
			
		||||
				valueType:   prometheus.GaugeValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
						return float64(fs.IoInProgress)
 | 
			
		||||
					})
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.IoQueued, "Total", asFloat64,
 | 
			
		||||
						s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
							return float64(fs.IoInProgress)
 | 
			
		||||
						},
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_io_time_seconds_total",
 | 
			
		||||
@@ -364,9 +441,12 @@ func NewPrometheusCollector(i infoProvider, f ContainerLabelsFunc) *PrometheusCo
 | 
			
		||||
				valueType:   prometheus.CounterValue,
 | 
			
		||||
				extraLabels: []string{"device"},
 | 
			
		||||
				getValues: func(s *info.ContainerStats) metricValues {
 | 
			
		||||
					return fsValues(s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
						return float64(float64(fs.IoTime) / float64(time.Second))
 | 
			
		||||
					})
 | 
			
		||||
					return ioValues(
 | 
			
		||||
						s.DiskIo.IoServiceTime, "Total", asNanosecondsToSeconds,
 | 
			
		||||
						s.Filesystem, func(fs *info.FsStats) float64 {
 | 
			
		||||
							return float64(float64(fs.IoTime) / float64(time.Second))
 | 
			
		||||
						},
 | 
			
		||||
					)
 | 
			
		||||
				},
 | 
			
		||||
			}, {
 | 
			
		||||
				name:        "container_fs_io_time_weighted_seconds_total",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								vendor/github.com/prometheus/client_golang/AUTHORS.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/prometheus/client_golang/AUTHORS.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,18 +0,0 @@
 | 
			
		||||
The Prometheus project was started by Matt T. Proud (emeritus) and
 | 
			
		||||
Julius Volz in 2012.
 | 
			
		||||
 | 
			
		||||
Maintainers of this repository:
 | 
			
		||||
 | 
			
		||||
* Björn Rabenstein <beorn@soundcloud.com>
 | 
			
		||||
 | 
			
		||||
The following individuals have contributed code to this repository
 | 
			
		||||
(listed in alphabetical order):
 | 
			
		||||
 | 
			
		||||
* Bernerd Schaefer <bj.schaefer@gmail.com>
 | 
			
		||||
* Björn Rabenstein <beorn@soundcloud.com>
 | 
			
		||||
* Daniel Bornkessel <daniel@soundcloud.com>
 | 
			
		||||
* Jeff Younker <jeff@drinktomi.com>
 | 
			
		||||
* Julius Volz <julius@soundcloud.com>
 | 
			
		||||
* Matt T. Proud <matt.proud@gmail.com>
 | 
			
		||||
* Tobias Schmidt <ts@soundcloud.com>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/github.com/prometheus/client_golang/NOTICE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/prometheus/client_golang/NOTICE
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -7,11 +7,6 @@ SoundCloud Ltd. (http://soundcloud.com/).
 | 
			
		||||
 | 
			
		||||
The following components are included in this product:
 | 
			
		||||
 | 
			
		||||
goautoneg
 | 
			
		||||
http://bitbucket.org/ww/goautoneg
 | 
			
		||||
Copyright 2011, Open Knowledge Foundation Ltd.
 | 
			
		||||
See README.txt for license details.
 | 
			
		||||
 | 
			
		||||
perks - a fork of https://github.com/bmizerany/perks
 | 
			
		||||
https://github.com/beorn7/perks
 | 
			
		||||
Copyright 2013-2015 Blake Mizerany, Björn Rabenstein
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/github.com/prometheus/client_golang/prometheus/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/prometheus/client_golang/prometheus/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -14,16 +14,18 @@ go_library(
 | 
			
		||||
        "counter.go",
 | 
			
		||||
        "desc.go",
 | 
			
		||||
        "doc.go",
 | 
			
		||||
        "expvar.go",
 | 
			
		||||
        "expvar_collector.go",
 | 
			
		||||
        "fnv.go",
 | 
			
		||||
        "gauge.go",
 | 
			
		||||
        "go_collector.go",
 | 
			
		||||
        "histogram.go",
 | 
			
		||||
        "http.go",
 | 
			
		||||
        "metric.go",
 | 
			
		||||
        "observer.go",
 | 
			
		||||
        "process_collector.go",
 | 
			
		||||
        "push.go",
 | 
			
		||||
        "registry.go",
 | 
			
		||||
        "summary.go",
 | 
			
		||||
        "timer.go",
 | 
			
		||||
        "untyped.go",
 | 
			
		||||
        "value.go",
 | 
			
		||||
        "vec.go",
 | 
			
		||||
@@ -34,6 +36,7 @@ go_library(
 | 
			
		||||
        "//vendor/github.com/golang/protobuf/proto:go_default_library",
 | 
			
		||||
        "//vendor/github.com/prometheus/client_model/go:go_default_library",
 | 
			
		||||
        "//vendor/github.com/prometheus/common/expfmt:go_default_library",
 | 
			
		||||
        "//vendor/github.com/prometheus/common/model:go_default_library",
 | 
			
		||||
        "//vendor/github.com/prometheus/procfs:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
@@ -47,6 +50,9 @@ filegroup(
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
    name = "all-srcs",
 | 
			
		||||
    srcs = [":package-srcs"],
 | 
			
		||||
    srcs = [
 | 
			
		||||
        ":package-srcs",
 | 
			
		||||
        "//vendor/github.com/prometheus/client_golang/prometheus/promhttp:all-srcs",
 | 
			
		||||
    ],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										54
									
								
								vendor/github.com/prometheus/client_golang/prometheus/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/github.com/prometheus/client_golang/prometheus/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,53 +1 @@
 | 
			
		||||
# Overview
 | 
			
		||||
This is the [Prometheus](http://www.prometheus.io) telemetric
 | 
			
		||||
instrumentation client [Go](http://golang.org) client library.  It
 | 
			
		||||
enable authors to define process-space metrics for their servers and
 | 
			
		||||
expose them through a web service interface for extraction,
 | 
			
		||||
aggregation, and a whole slew of other post processing techniques.
 | 
			
		||||
 | 
			
		||||
# Installing
 | 
			
		||||
    $ go get github.com/prometheus/client_golang/prometheus
 | 
			
		||||
 | 
			
		||||
# Example
 | 
			
		||||
```go
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"github.com/prometheus/client_golang/prometheus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	indexed = prometheus.NewCounter(prometheus.CounterOpts{
 | 
			
		||||
		Namespace: "my_company",
 | 
			
		||||
		Subsystem: "indexer",
 | 
			
		||||
		Name:      "documents_indexed",
 | 
			
		||||
		Help:      "The number of documents indexed.",
 | 
			
		||||
	})
 | 
			
		||||
	size = prometheus.NewGauge(prometheus.GaugeOpts{
 | 
			
		||||
		Namespace: "my_company",
 | 
			
		||||
		Subsystem: "storage",
 | 
			
		||||
		Name:      "documents_total_size_bytes",
 | 
			
		||||
		Help:      "The total size of all documents in the storage.",
 | 
			
		||||
	})
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	http.Handle("/metrics", prometheus.Handler())
 | 
			
		||||
 | 
			
		||||
	indexed.Inc()
 | 
			
		||||
	size.Set(5)
 | 
			
		||||
 | 
			
		||||
	http.ListenAndServe(":8080", nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	prometheus.MustRegister(indexed)
 | 
			
		||||
	prometheus.MustRegister(size)
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
# Documentation
 | 
			
		||||
 | 
			
		||||
[](https://godoc.org/github.com/prometheus/client_golang)
 | 
			
		||||
See [](https://godoc.org/github.com/prometheus/client_golang/prometheus).
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								vendor/github.com/prometheus/client_golang/prometheus/collector.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/prometheus/client_golang/prometheus/collector.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -15,15 +15,15 @@ package prometheus
 | 
			
		||||
 | 
			
		||||
// Collector is the interface implemented by anything that can be used by
 | 
			
		||||
// Prometheus to collect metrics. A Collector has to be registered for
 | 
			
		||||
// collection. See Register, MustRegister, RegisterOrGet, and MustRegisterOrGet.
 | 
			
		||||
// collection. See Registerer.Register.
 | 
			
		||||
//
 | 
			
		||||
// The stock metrics provided by this package (like Gauge, Counter, Summary) are
 | 
			
		||||
// also Collectors (which only ever collect one metric, namely itself). An
 | 
			
		||||
// implementer of Collector may, however, collect multiple metrics in a
 | 
			
		||||
// coordinated fashion and/or create metrics on the fly. Examples for collectors
 | 
			
		||||
// already implemented in this library are the metric vectors (i.e. collection
 | 
			
		||||
// of multiple instances of the same Metric but with different label values)
 | 
			
		||||
// like GaugeVec or SummaryVec, and the ExpvarCollector.
 | 
			
		||||
// The stock metrics provided by this package (Gauge, Counter, Summary,
 | 
			
		||||
// Histogram, Untyped) are also Collectors (which only ever collect one metric,
 | 
			
		||||
// namely itself). An implementer of Collector may, however, collect multiple
 | 
			
		||||
// metrics in a coordinated fashion and/or create metrics on the fly. Examples
 | 
			
		||||
// for collectors already implemented in this library are the metric vectors
 | 
			
		||||
// (i.e. collection of multiple instances of the same Metric but with different
 | 
			
		||||
// label values) like GaugeVec or SummaryVec, and the ExpvarCollector.
 | 
			
		||||
type Collector interface {
 | 
			
		||||
	// Describe sends the super-set of all possible descriptors of metrics
 | 
			
		||||
	// collected by this Collector to the provided channel and returns once
 | 
			
		||||
@@ -37,39 +37,39 @@ type Collector interface {
 | 
			
		||||
	// executing this method, it must send an invalid descriptor (created
 | 
			
		||||
	// with NewInvalidDesc) to signal the error to the registry.
 | 
			
		||||
	Describe(chan<- *Desc)
 | 
			
		||||
	// Collect is called by Prometheus when collecting metrics. The
 | 
			
		||||
	// implementation sends each collected metric via the provided channel
 | 
			
		||||
	// and returns once the last metric has been sent. The descriptor of
 | 
			
		||||
	// each sent metric is one of those returned by Describe. Returned
 | 
			
		||||
	// metrics that share the same descriptor must differ in their variable
 | 
			
		||||
	// label values. This method may be called concurrently and must
 | 
			
		||||
	// therefore be implemented in a concurrency safe way. Blocking occurs
 | 
			
		||||
	// at the expense of total performance of rendering all registered
 | 
			
		||||
	// metrics. Ideally, Collector implementations support concurrent
 | 
			
		||||
	// readers.
 | 
			
		||||
	// Collect is called by the Prometheus registry when collecting
 | 
			
		||||
	// metrics. The implementation sends each collected metric via the
 | 
			
		||||
	// provided channel and returns once the last metric has been sent. The
 | 
			
		||||
	// descriptor of each sent metric is one of those returned by
 | 
			
		||||
	// Describe. Returned metrics that share the same descriptor must differ
 | 
			
		||||
	// in their variable label values. This method may be called
 | 
			
		||||
	// concurrently and must therefore be implemented in a concurrency safe
 | 
			
		||||
	// way. Blocking occurs at the expense of total performance of rendering
 | 
			
		||||
	// all registered metrics. Ideally, Collector implementations support
 | 
			
		||||
	// concurrent readers.
 | 
			
		||||
	Collect(chan<- Metric)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SelfCollector implements Collector for a single Metric so that that the
 | 
			
		||||
// Metric collects itself. Add it as an anonymous field to a struct that
 | 
			
		||||
// implements Metric, and call Init with the Metric itself as an argument.
 | 
			
		||||
type SelfCollector struct {
 | 
			
		||||
// selfCollector implements Collector for a single Metric so that the Metric
 | 
			
		||||
// collects itself. Add it as an anonymous field to a struct that implements
 | 
			
		||||
// Metric, and call init with the Metric itself as an argument.
 | 
			
		||||
type selfCollector struct {
 | 
			
		||||
	self Metric
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Init provides the SelfCollector with a reference to the metric it is supposed
 | 
			
		||||
// init provides the selfCollector with a reference to the metric it is supposed
 | 
			
		||||
// to collect. It is usually called within the factory function to create a
 | 
			
		||||
// metric. See example.
 | 
			
		||||
func (c *SelfCollector) Init(self Metric) {
 | 
			
		||||
func (c *selfCollector) init(self Metric) {
 | 
			
		||||
	c.self = self
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Describe implements Collector.
 | 
			
		||||
func (c *SelfCollector) Describe(ch chan<- *Desc) {
 | 
			
		||||
func (c *selfCollector) Describe(ch chan<- *Desc) {
 | 
			
		||||
	ch <- c.self.Desc()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Collect implements Collector.
 | 
			
		||||
func (c *SelfCollector) Collect(ch chan<- Metric) {
 | 
			
		||||
func (c *selfCollector) Collect(ch chan<- Metric) {
 | 
			
		||||
	ch <- c.self
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								vendor/github.com/prometheus/client_golang/prometheus/counter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/prometheus/client_golang/prometheus/counter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -15,7 +15,6 @@ package prometheus
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"hash/fnv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Counter is a Metric that represents a single numerical value that only ever
 | 
			
		||||
@@ -31,13 +30,8 @@ type Counter interface {
 | 
			
		||||
	Metric
 | 
			
		||||
	Collector
 | 
			
		||||
 | 
			
		||||
	// Set is used to set the Counter to an arbitrary value. It is only used
 | 
			
		||||
	// if you have to transfer a value from an external counter into this
 | 
			
		||||
	// Prometheus metric. Do not use it for regular handling of a
 | 
			
		||||
	// Prometheus counter (as it can be used to break the contract of
 | 
			
		||||
	// monotonically increasing values).
 | 
			
		||||
	Set(float64)
 | 
			
		||||
	// Inc increments the counter by 1.
 | 
			
		||||
	// Inc increments the counter by 1. Use Add to increment it by arbitrary
 | 
			
		||||
	// non-negative values.
 | 
			
		||||
	Inc()
 | 
			
		||||
	// Add adds the given value to the counter. It panics if the value is <
 | 
			
		||||
	// 0.
 | 
			
		||||
@@ -56,7 +50,7 @@ func NewCounter(opts CounterOpts) Counter {
 | 
			
		||||
		opts.ConstLabels,
 | 
			
		||||
	)
 | 
			
		||||
	result := &counter{value: value{desc: desc, valType: CounterValue, labelPairs: desc.constLabelPairs}}
 | 
			
		||||
	result.Init(result) // Init self-collection.
 | 
			
		||||
	result.init(result) // Init self-collection.
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -80,7 +74,7 @@ func (c *counter) Add(v float64) {
 | 
			
		||||
// CounterVec embeds MetricVec. See there for a full list of methods with
 | 
			
		||||
// detailed documentation.
 | 
			
		||||
type CounterVec struct {
 | 
			
		||||
	MetricVec
 | 
			
		||||
	*MetricVec
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewCounterVec creates a new CounterVec based on the provided CounterOpts and
 | 
			
		||||
@@ -94,20 +88,15 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
 | 
			
		||||
		opts.ConstLabels,
 | 
			
		||||
	)
 | 
			
		||||
	return &CounterVec{
 | 
			
		||||
		MetricVec: MetricVec{
 | 
			
		||||
			children: map[uint64]Metric{},
 | 
			
		||||
			desc:     desc,
 | 
			
		||||
			hash:     fnv.New64a(),
 | 
			
		||||
			newMetric: func(lvs ...string) Metric {
 | 
			
		||||
				result := &counter{value: value{
 | 
			
		||||
					desc:       desc,
 | 
			
		||||
					valType:    CounterValue,
 | 
			
		||||
					labelPairs: makeLabelPairs(desc, lvs),
 | 
			
		||||
				}}
 | 
			
		||||
				result.Init(result) // Init self-collection.
 | 
			
		||||
				return result
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
 | 
			
		||||
			result := &counter{value: value{
 | 
			
		||||
				desc:       desc,
 | 
			
		||||
				valType:    CounterValue,
 | 
			
		||||
				labelPairs: makeLabelPairs(desc, lvs),
 | 
			
		||||
			}}
 | 
			
		||||
			result.init(result) // Init self-collection.
 | 
			
		||||
			return result
 | 
			
		||||
		}),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										55
									
								
								vendor/github.com/prometheus/client_golang/prometheus/desc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										55
									
								
								vendor/github.com/prometheus/client_golang/prometheus/desc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,24 +1,30 @@
 | 
			
		||||
// Copyright 2016 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package prometheus
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"hash/fnv"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/golang/protobuf/proto"
 | 
			
		||||
	"github.com/prometheus/common/model"
 | 
			
		||||
 | 
			
		||||
	dto "github.com/prometheus/client_model/go"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	metricNameRE = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_:]*$`)
 | 
			
		||||
	labelNameRE  = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// reservedLabelPrefix is a prefix which is not legal in user-supplied
 | 
			
		||||
// label names.
 | 
			
		||||
const reservedLabelPrefix = "__"
 | 
			
		||||
@@ -67,7 +73,7 @@ type Desc struct {
 | 
			
		||||
	// Help string. Each Desc with the same fqName must have the same
 | 
			
		||||
	// dimHash.
 | 
			
		||||
	dimHash uint64
 | 
			
		||||
	// err is an error that occured during construction. It is reported on
 | 
			
		||||
	// err is an error that occurred during construction. It is reported on
 | 
			
		||||
	// registration time.
 | 
			
		||||
	err error
 | 
			
		||||
}
 | 
			
		||||
@@ -92,7 +98,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
 | 
			
		||||
		d.err = errors.New("empty help string")
 | 
			
		||||
		return d
 | 
			
		||||
	}
 | 
			
		||||
	if !metricNameRE.MatchString(fqName) {
 | 
			
		||||
	if !model.IsValidMetricName(model.LabelValue(fqName)) {
 | 
			
		||||
		d.err = fmt.Errorf("%q is not a valid metric name", fqName)
 | 
			
		||||
		return d
 | 
			
		||||
	}
 | 
			
		||||
@@ -131,31 +137,24 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
 | 
			
		||||
		d.err = errors.New("duplicate label names")
 | 
			
		||||
		return d
 | 
			
		||||
	}
 | 
			
		||||
	h := fnv.New64a()
 | 
			
		||||
	var b bytes.Buffer // To copy string contents into, avoiding []byte allocations.
 | 
			
		||||
	vh := hashNew()
 | 
			
		||||
	for _, val := range labelValues {
 | 
			
		||||
		b.Reset()
 | 
			
		||||
		b.WriteString(val)
 | 
			
		||||
		b.WriteByte(separatorByte)
 | 
			
		||||
		h.Write(b.Bytes())
 | 
			
		||||
		vh = hashAdd(vh, val)
 | 
			
		||||
		vh = hashAddByte(vh, separatorByte)
 | 
			
		||||
	}
 | 
			
		||||
	d.id = h.Sum64()
 | 
			
		||||
	d.id = vh
 | 
			
		||||
	// Sort labelNames so that order doesn't matter for the hash.
 | 
			
		||||
	sort.Strings(labelNames)
 | 
			
		||||
	// Now hash together (in this order) the help string and the sorted
 | 
			
		||||
	// label names.
 | 
			
		||||
	h.Reset()
 | 
			
		||||
	b.Reset()
 | 
			
		||||
	b.WriteString(help)
 | 
			
		||||
	b.WriteByte(separatorByte)
 | 
			
		||||
	h.Write(b.Bytes())
 | 
			
		||||
	lh := hashNew()
 | 
			
		||||
	lh = hashAdd(lh, help)
 | 
			
		||||
	lh = hashAddByte(lh, separatorByte)
 | 
			
		||||
	for _, labelName := range labelNames {
 | 
			
		||||
		b.Reset()
 | 
			
		||||
		b.WriteString(labelName)
 | 
			
		||||
		b.WriteByte(separatorByte)
 | 
			
		||||
		h.Write(b.Bytes())
 | 
			
		||||
		lh = hashAdd(lh, labelName)
 | 
			
		||||
		lh = hashAddByte(lh, separatorByte)
 | 
			
		||||
	}
 | 
			
		||||
	d.dimHash = h.Sum64()
 | 
			
		||||
	d.dimHash = lh
 | 
			
		||||
 | 
			
		||||
	d.constLabelPairs = make([]*dto.LabelPair, 0, len(constLabels))
 | 
			
		||||
	for n, v := range constLabels {
 | 
			
		||||
@@ -196,6 +195,6 @@ func (d *Desc) String() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func checkLabelName(l string) bool {
 | 
			
		||||
	return labelNameRE.MatchString(l) &&
 | 
			
		||||
	return model.LabelName(l).IsValid() &&
 | 
			
		||||
		!strings.HasPrefix(l, reservedLabelPrefix)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										183
									
								
								vendor/github.com/prometheus/client_golang/prometheus/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										183
									
								
								vendor/github.com/prometheus/client_golang/prometheus/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -11,25 +11,26 @@
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// Package prometheus provides embeddable metric primitives for servers and
 | 
			
		||||
// standardized exposition of telemetry through a web services interface.
 | 
			
		||||
// Package prometheus provides metrics primitives to instrument code for
 | 
			
		||||
// monitoring. It also offers a registry for metrics. Sub-packages allow to
 | 
			
		||||
// expose the registered metrics via HTTP (package promhttp) or push them to a
 | 
			
		||||
// Pushgateway (package push).
 | 
			
		||||
//
 | 
			
		||||
// All exported functions and methods are safe to be used concurrently unless
 | 
			
		||||
// specified otherwise.
 | 
			
		||||
//
 | 
			
		||||
// To expose metrics registered with the Prometheus registry, an HTTP server
 | 
			
		||||
// needs to know about the Prometheus handler. The usual endpoint is "/metrics".
 | 
			
		||||
// A Basic Example
 | 
			
		||||
//
 | 
			
		||||
//     http.Handle("/metrics", prometheus.Handler())
 | 
			
		||||
//
 | 
			
		||||
// As a starting point a very basic usage example:
 | 
			
		||||
// As a starting point, a very basic usage example:
 | 
			
		||||
//
 | 
			
		||||
//    package main
 | 
			
		||||
//
 | 
			
		||||
//    import (
 | 
			
		||||
//    	"log"
 | 
			
		||||
//    	"net/http"
 | 
			
		||||
//
 | 
			
		||||
//    	"github.com/prometheus/client_golang/prometheus"
 | 
			
		||||
//    	"github.com/prometheus/client_golang/prometheus/promhttp"
 | 
			
		||||
//    )
 | 
			
		||||
//
 | 
			
		||||
//    var (
 | 
			
		||||
@@ -37,73 +38,149 @@
 | 
			
		||||
//    		Name: "cpu_temperature_celsius",
 | 
			
		||||
//    		Help: "Current temperature of the CPU.",
 | 
			
		||||
//    	})
 | 
			
		||||
//    	hdFailures = prometheus.NewCounter(prometheus.CounterOpts{
 | 
			
		||||
//    		Name: "hd_errors_total",
 | 
			
		||||
//    		Help: "Number of hard-disk errors.",
 | 
			
		||||
//    	})
 | 
			
		||||
//    	hdFailures = prometheus.NewCounterVec(
 | 
			
		||||
//    		prometheus.CounterOpts{
 | 
			
		||||
//    			Name: "hd_errors_total",
 | 
			
		||||
//    			Help: "Number of hard-disk errors.",
 | 
			
		||||
//    		},
 | 
			
		||||
//    		[]string{"device"},
 | 
			
		||||
//    	)
 | 
			
		||||
//    )
 | 
			
		||||
//
 | 
			
		||||
//    func init() {
 | 
			
		||||
//    	// Metrics have to be registered to be exposed:
 | 
			
		||||
//    	prometheus.MustRegister(cpuTemp)
 | 
			
		||||
//    	prometheus.MustRegister(hdFailures)
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    func main() {
 | 
			
		||||
//    	cpuTemp.Set(65.3)
 | 
			
		||||
//    	hdFailures.Inc()
 | 
			
		||||
//    	hdFailures.With(prometheus.Labels{"device":"/dev/sda"}).Inc()
 | 
			
		||||
//
 | 
			
		||||
//    	http.Handle("/metrics", prometheus.Handler())
 | 
			
		||||
//    	http.ListenAndServe(":8080", nil)
 | 
			
		||||
//    	// The Handler function provides a default handler to expose metrics
 | 
			
		||||
//    	// via an HTTP server. "/metrics" is the usual endpoint for that.
 | 
			
		||||
//    	http.Handle("/metrics", promhttp.Handler())
 | 
			
		||||
//      log.Fatal(http.ListenAndServe(":8080", nil))
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// This is a complete program that exports two metrics, a Gauge and a Counter.
 | 
			
		||||
// It also exports some stats about the HTTP usage of the /metrics
 | 
			
		||||
// endpoint. (See the Handler function for more detail.)
 | 
			
		||||
// This is a complete program that exports two metrics, a Gauge and a Counter,
 | 
			
		||||
// the latter with a label attached to turn it into a (one-dimensional) vector.
 | 
			
		||||
//
 | 
			
		||||
// Two more advanced metric types are the Summary and Histogram.
 | 
			
		||||
// Metrics
 | 
			
		||||
//
 | 
			
		||||
// In addition to the fundamental metric types Gauge, Counter, Summary, and
 | 
			
		||||
// Histogram, a very important part of the Prometheus data model is the
 | 
			
		||||
// partitioning of samples along dimensions called labels, which results in
 | 
			
		||||
// The number of exported identifiers in this package might appear a bit
 | 
			
		||||
// overwhelming. However, in addition to the basic plumbing shown in the example
 | 
			
		||||
// above, you only need to understand the different metric types and their
 | 
			
		||||
// vector versions for basic usage.
 | 
			
		||||
//
 | 
			
		||||
// Above, you have already touched the Counter and the Gauge. There are two more
 | 
			
		||||
// advanced metric types: the Summary and Histogram. A more thorough description
 | 
			
		||||
// of those four metric types can be found in the Prometheus docs:
 | 
			
		||||
// https://prometheus.io/docs/concepts/metric_types/
 | 
			
		||||
//
 | 
			
		||||
// A fifth "type" of metric is Untyped. It behaves like a Gauge, but signals the
 | 
			
		||||
// Prometheus server not to assume anything about its type.
 | 
			
		||||
//
 | 
			
		||||
// In addition to the fundamental metric types Gauge, Counter, Summary,
 | 
			
		||||
// Histogram, and Untyped, a very important part of the Prometheus data model is
 | 
			
		||||
// the partitioning of samples along dimensions called labels, which results in
 | 
			
		||||
// metric vectors. The fundamental types are GaugeVec, CounterVec, SummaryVec,
 | 
			
		||||
// and HistogramVec.
 | 
			
		||||
// HistogramVec, and UntypedVec.
 | 
			
		||||
//
 | 
			
		||||
// Those are all the parts needed for basic usage. Detailed documentation and
 | 
			
		||||
// examples are provided below.
 | 
			
		||||
// While only the fundamental metric types implement the Metric interface, both
 | 
			
		||||
// the metrics and their vector versions implement the Collector interface. A
 | 
			
		||||
// Collector manages the collection of a number of Metrics, but for convenience,
 | 
			
		||||
// a Metric can also “collect itself”. Note that Gauge, Counter, Summary,
 | 
			
		||||
// Histogram, and Untyped are interfaces themselves while GaugeVec, CounterVec,
 | 
			
		||||
// SummaryVec, HistogramVec, and UntypedVec are not.
 | 
			
		||||
//
 | 
			
		||||
// Everything else this package offers is essentially for "power users" only. A
 | 
			
		||||
// few pointers to "power user features":
 | 
			
		||||
// To create instances of Metrics and their vector versions, you need a suitable
 | 
			
		||||
// …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, HistogramOpts, or
 | 
			
		||||
// UntypedOpts.
 | 
			
		||||
//
 | 
			
		||||
// All the various ...Opts structs have a ConstLabels field for labels that
 | 
			
		||||
// never change their value (which is only useful under special circumstances,
 | 
			
		||||
// see documentation of the Opts type).
 | 
			
		||||
// Custom Collectors and constant Metrics
 | 
			
		||||
//
 | 
			
		||||
// The Untyped metric behaves like a Gauge, but signals the Prometheus server
 | 
			
		||||
// not to assume anything about its type.
 | 
			
		||||
// While you could create your own implementations of Metric, most likely you
 | 
			
		||||
// will only ever implement the Collector interface on your own. At a first
 | 
			
		||||
// glance, a custom Collector seems handy to bundle Metrics for common
 | 
			
		||||
// registration (with the prime example of the different metric vectors above,
 | 
			
		||||
// which bundle all the metrics of the same name but with different labels).
 | 
			
		||||
//
 | 
			
		||||
// Functions to fine-tune how the metric registry works: EnableCollectChecks,
 | 
			
		||||
// PanicOnCollectError, Register, Unregister, SetMetricFamilyInjectionHook.
 | 
			
		||||
// There is a more involved use case, too: If you already have metrics
 | 
			
		||||
// available, created outside of the Prometheus context, you don't need the
 | 
			
		||||
// interface of the various Metric types. You essentially want to mirror the
 | 
			
		||||
// existing numbers into Prometheus Metrics during collection. An own
 | 
			
		||||
// implementation of the Collector interface is perfect for that. You can create
 | 
			
		||||
// Metric instances “on the fly” using NewConstMetric, NewConstHistogram, and
 | 
			
		||||
// NewConstSummary (and their respective Must… versions). That will happen in
 | 
			
		||||
// the Collect method. The Describe method has to return separate Desc
 | 
			
		||||
// instances, representative of the “throw-away” metrics to be created later.
 | 
			
		||||
// NewDesc comes in handy to create those Desc instances.
 | 
			
		||||
//
 | 
			
		||||
// For custom metric collection, there are two entry points: Custom Metric
 | 
			
		||||
// implementations and custom Collector implementations. A Metric is the
 | 
			
		||||
// fundamental unit in the Prometheus data model: a sample at a point in time
 | 
			
		||||
// together with its meta-data (like its fully-qualified name and any number of
 | 
			
		||||
// pairs of label name and label value) that knows how to marshal itself into a
 | 
			
		||||
// data transfer object (aka DTO, implemented as a protocol buffer). A Collector
 | 
			
		||||
// gets registered with the Prometheus registry and manages the collection of
 | 
			
		||||
// one or more Metrics. Many parts of this package are building blocks for
 | 
			
		||||
// Metrics and Collectors. Desc is the metric descriptor, actually used by all
 | 
			
		||||
// metrics under the hood, and by Collectors to describe the Metrics to be
 | 
			
		||||
// collected, but only to be dealt with by users if they implement their own
 | 
			
		||||
// Metrics or Collectors. To create a Desc, the BuildFQName function will come
 | 
			
		||||
// in handy. Other useful components for Metric and Collector implementation
 | 
			
		||||
// include: LabelPairSorter to sort the DTO version of label pairs,
 | 
			
		||||
// NewConstMetric and MustNewConstMetric to create "throw away" Metrics at
 | 
			
		||||
// collection time, MetricVec to bundle custom Metrics into a metric vector
 | 
			
		||||
// Collector, SelfCollector to make a custom Metric collect itself.
 | 
			
		||||
// The Collector example illustrates the use case. You can also look at the
 | 
			
		||||
// source code of the processCollector (mirroring process metrics), the
 | 
			
		||||
// goCollector (mirroring Go metrics), or the expvarCollector (mirroring expvar
 | 
			
		||||
// metrics) as examples that are used in this package itself.
 | 
			
		||||
//
 | 
			
		||||
// A good example for a custom Collector is the ExpVarCollector included in this
 | 
			
		||||
// package, which exports variables exported via the "expvar" package as
 | 
			
		||||
// Prometheus metrics.
 | 
			
		||||
// If you just need to call a function to get a single float value to collect as
 | 
			
		||||
// a metric, GaugeFunc, CounterFunc, or UntypedFunc might be interesting
 | 
			
		||||
// shortcuts.
 | 
			
		||||
//
 | 
			
		||||
// Advanced Uses of the Registry
 | 
			
		||||
//
 | 
			
		||||
// While MustRegister is the by far most common way of registering a Collector,
 | 
			
		||||
// sometimes you might want to handle the errors the registration might cause.
 | 
			
		||||
// As suggested by the name, MustRegister panics if an error occurs. With the
 | 
			
		||||
// Register function, the error is returned and can be handled.
 | 
			
		||||
//
 | 
			
		||||
// An error is returned if the registered Collector is incompatible or
 | 
			
		||||
// inconsistent with already registered metrics. The registry aims for
 | 
			
		||||
// consistency of the collected metrics according to the Prometheus data model.
 | 
			
		||||
// Inconsistencies are ideally detected at registration time, not at collect
 | 
			
		||||
// time. The former will usually be detected at start-up time of a program,
 | 
			
		||||
// while the latter will only happen at scrape time, possibly not even on the
 | 
			
		||||
// first scrape if the inconsistency only becomes relevant later. That is the
 | 
			
		||||
// main reason why a Collector and a Metric have to describe themselves to the
 | 
			
		||||
// registry.
 | 
			
		||||
//
 | 
			
		||||
// So far, everything we did operated on the so-called default registry, as it
 | 
			
		||||
// can be found in the global DefaultRegistry variable. With NewRegistry, you
 | 
			
		||||
// can create a custom registry, or you can even implement the Registerer or
 | 
			
		||||
// Gatherer interfaces yourself. The methods Register and Unregister work in the
 | 
			
		||||
// same way on a custom registry as the global functions Register and Unregister
 | 
			
		||||
// on the default registry.
 | 
			
		||||
//
 | 
			
		||||
// There are a number of uses for custom registries: You can use registries with
 | 
			
		||||
// special properties, see NewPedanticRegistry. You can avoid global state, as
 | 
			
		||||
// it is imposed by the DefaultRegistry. You can use multiple registries at the
 | 
			
		||||
// same time to expose different metrics in different ways. You can use separate
 | 
			
		||||
// registries for testing purposes.
 | 
			
		||||
//
 | 
			
		||||
// Also note that the DefaultRegistry comes registered with a Collector for Go
 | 
			
		||||
// runtime metrics (via NewGoCollector) and a Collector for process metrics (via
 | 
			
		||||
// NewProcessCollector). With a custom registry, you are in control and decide
 | 
			
		||||
// yourself about the Collectors to register.
 | 
			
		||||
//
 | 
			
		||||
// HTTP Exposition
 | 
			
		||||
//
 | 
			
		||||
// The Registry implements the Gatherer interface. The caller of the Gather
 | 
			
		||||
// method can then expose the gathered metrics in some way. Usually, the metrics
 | 
			
		||||
// are served via HTTP on the /metrics endpoint. That's happening in the example
 | 
			
		||||
// above. The tools to expose metrics via HTTP are in the promhttp sub-package.
 | 
			
		||||
// (The top-level functions in the prometheus package are deprecated.)
 | 
			
		||||
//
 | 
			
		||||
// Pushing to the Pushgateway
 | 
			
		||||
//
 | 
			
		||||
// Function for pushing to the Pushgateway can be found in the push sub-package.
 | 
			
		||||
//
 | 
			
		||||
// Graphite Bridge
 | 
			
		||||
//
 | 
			
		||||
// Functions and examples to push metrics from a Gatherer to Graphite can be
 | 
			
		||||
// found in the graphite sub-package.
 | 
			
		||||
//
 | 
			
		||||
// Other Means of Exposition
 | 
			
		||||
//
 | 
			
		||||
// More ways of exposing metrics can easily be added by following the approaches
 | 
			
		||||
// of the existing implementations.
 | 
			
		||||
package prometheus
 | 
			
		||||
 
 | 
			
		||||
@@ -18,21 +18,21 @@ import (
 | 
			
		||||
	"expvar"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ExpvarCollector collects metrics from the expvar interface. It provides a
 | 
			
		||||
// quick way to expose numeric values that are already exported via expvar as
 | 
			
		||||
// Prometheus metrics. Note that the data models of expvar and Prometheus are
 | 
			
		||||
// fundamentally different, and that the ExpvarCollector is inherently
 | 
			
		||||
// slow. Thus, the ExpvarCollector is probably great for experiments and
 | 
			
		||||
// prototying, but you should seriously consider a more direct implementation of
 | 
			
		||||
// Prometheus metrics for monitoring production systems.
 | 
			
		||||
//
 | 
			
		||||
// Use NewExpvarCollector to create new instances.
 | 
			
		||||
type ExpvarCollector struct {
 | 
			
		||||
type expvarCollector struct {
 | 
			
		||||
	exports map[string]*Desc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewExpvarCollector returns a newly allocated ExpvarCollector that still has
 | 
			
		||||
// to be registered with the Prometheus registry.
 | 
			
		||||
// NewExpvarCollector returns a newly allocated expvar Collector that still has
 | 
			
		||||
// to be registered with a Prometheus registry.
 | 
			
		||||
//
 | 
			
		||||
// An expvar Collector collects metrics from the expvar interface. It provides a
 | 
			
		||||
// quick way to expose numeric values that are already exported via expvar as
 | 
			
		||||
// Prometheus metrics. Note that the data models of expvar and Prometheus are
 | 
			
		||||
// fundamentally different, and that the expvar Collector is inherently slower
 | 
			
		||||
// than native Prometheus metrics. Thus, the expvar Collector is probably great
 | 
			
		||||
// for experiments and prototying, but you should seriously consider a more
 | 
			
		||||
// direct implementation of Prometheus metrics for monitoring production
 | 
			
		||||
// systems.
 | 
			
		||||
//
 | 
			
		||||
// The exports map has the following meaning:
 | 
			
		||||
//
 | 
			
		||||
@@ -59,21 +59,21 @@ type ExpvarCollector struct {
 | 
			
		||||
// sample values.
 | 
			
		||||
//
 | 
			
		||||
// Anything that does not fit into the scheme above is silently ignored.
 | 
			
		||||
func NewExpvarCollector(exports map[string]*Desc) *ExpvarCollector {
 | 
			
		||||
	return &ExpvarCollector{
 | 
			
		||||
func NewExpvarCollector(exports map[string]*Desc) Collector {
 | 
			
		||||
	return &expvarCollector{
 | 
			
		||||
		exports: exports,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Describe implements Collector.
 | 
			
		||||
func (e *ExpvarCollector) Describe(ch chan<- *Desc) {
 | 
			
		||||
func (e *expvarCollector) Describe(ch chan<- *Desc) {
 | 
			
		||||
	for _, desc := range e.exports {
 | 
			
		||||
		ch <- desc
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Collect implements Collector.
 | 
			
		||||
func (e *ExpvarCollector) Collect(ch chan<- Metric) {
 | 
			
		||||
func (e *expvarCollector) Collect(ch chan<- Metric) {
 | 
			
		||||
	for name, desc := range e.exports {
 | 
			
		||||
		var m Metric
 | 
			
		||||
		expVar := expvar.Get(name)
 | 
			
		||||
							
								
								
									
										29
									
								
								vendor/github.com/prometheus/client_golang/prometheus/fnv.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/prometheus/client_golang/prometheus/fnv.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
package prometheus
 | 
			
		||||
 | 
			
		||||
// Inline and byte-free variant of hash/fnv's fnv64a.
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	offset64 = 14695981039346656037
 | 
			
		||||
	prime64  = 1099511628211
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// hashNew initializies a new fnv64a hash value.
 | 
			
		||||
func hashNew() uint64 {
 | 
			
		||||
	return offset64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// hashAdd adds a string to a fnv64a hash value, returning the updated hash.
 | 
			
		||||
func hashAdd(h uint64, s string) uint64 {
 | 
			
		||||
	for i := 0; i < len(s); i++ {
 | 
			
		||||
		h ^= uint64(s[i])
 | 
			
		||||
		h *= prime64
 | 
			
		||||
	}
 | 
			
		||||
	return h
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.
 | 
			
		||||
func hashAddByte(h uint64, b byte) uint64 {
 | 
			
		||||
	h ^= uint64(b)
 | 
			
		||||
	h *= prime64
 | 
			
		||||
	return h
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								vendor/github.com/prometheus/client_golang/prometheus/gauge.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/prometheus/client_golang/prometheus/gauge.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -13,8 +13,6 @@
 | 
			
		||||
 | 
			
		||||
package prometheus
 | 
			
		||||
 | 
			
		||||
import "hash/fnv"
 | 
			
		||||
 | 
			
		||||
// Gauge is a Metric that represents a single numerical value that can
 | 
			
		||||
// arbitrarily go up and down.
 | 
			
		||||
//
 | 
			
		||||
@@ -29,16 +27,21 @@ type Gauge interface {
 | 
			
		||||
 | 
			
		||||
	// Set sets the Gauge to an arbitrary value.
 | 
			
		||||
	Set(float64)
 | 
			
		||||
	// Inc increments the Gauge by 1.
 | 
			
		||||
	// Inc increments the Gauge by 1. Use Add to increment it by arbitrary
 | 
			
		||||
	// values.
 | 
			
		||||
	Inc()
 | 
			
		||||
	// Dec decrements the Gauge by 1.
 | 
			
		||||
	// Dec decrements the Gauge by 1. Use Sub to decrement it by arbitrary
 | 
			
		||||
	// values.
 | 
			
		||||
	Dec()
 | 
			
		||||
	// Add adds the given value to the Gauge. (The value can be
 | 
			
		||||
	// negative, resulting in a decrease of the Gauge.)
 | 
			
		||||
	// Add adds the given value to the Gauge. (The value can be negative,
 | 
			
		||||
	// resulting in a decrease of the Gauge.)
 | 
			
		||||
	Add(float64)
 | 
			
		||||
	// Sub subtracts the given value from the Gauge. (The value can be
 | 
			
		||||
	// negative, resulting in an increase of the Gauge.)
 | 
			
		||||
	Sub(float64)
 | 
			
		||||
 | 
			
		||||
	// SetToCurrentTime sets the Gauge to the current Unix time in seconds.
 | 
			
		||||
	SetToCurrentTime()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GaugeOpts is an alias for Opts. See there for doc comments.
 | 
			
		||||
@@ -60,7 +63,7 @@ func NewGauge(opts GaugeOpts) Gauge {
 | 
			
		||||
// (e.g. number of operations queued, partitioned by user and operation
 | 
			
		||||
// type). Create instances with NewGaugeVec.
 | 
			
		||||
type GaugeVec struct {
 | 
			
		||||
	MetricVec
 | 
			
		||||
	*MetricVec
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewGaugeVec creates a new GaugeVec based on the provided GaugeOpts and
 | 
			
		||||
@@ -74,14 +77,9 @@ func NewGaugeVec(opts GaugeOpts, labelNames []string) *GaugeVec {
 | 
			
		||||
		opts.ConstLabels,
 | 
			
		||||
	)
 | 
			
		||||
	return &GaugeVec{
 | 
			
		||||
		MetricVec: MetricVec{
 | 
			
		||||
			children: map[uint64]Metric{},
 | 
			
		||||
			desc:     desc,
 | 
			
		||||
			hash:     fnv.New64a(),
 | 
			
		||||
			newMetric: func(lvs ...string) Metric {
 | 
			
		||||
				return newValue(desc, GaugeValue, 0, lvs...)
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
 | 
			
		||||
			return newValue(desc, GaugeValue, 0, lvs...)
 | 
			
		||||
		}),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										47
									
								
								vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -8,8 +8,9 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type goCollector struct {
 | 
			
		||||
	goroutines Gauge
 | 
			
		||||
	gcDesc     *Desc
 | 
			
		||||
	goroutinesDesc *Desc
 | 
			
		||||
	threadsDesc    *Desc
 | 
			
		||||
	gcDesc         *Desc
 | 
			
		||||
 | 
			
		||||
	// metrics to describe and collect
 | 
			
		||||
	metrics memStatsMetrics
 | 
			
		||||
@@ -17,13 +18,16 @@ type goCollector struct {
 | 
			
		||||
 | 
			
		||||
// NewGoCollector returns a collector which exports metrics about the current
 | 
			
		||||
// go process.
 | 
			
		||||
func NewGoCollector() *goCollector {
 | 
			
		||||
func NewGoCollector() Collector {
 | 
			
		||||
	return &goCollector{
 | 
			
		||||
		goroutines: NewGauge(GaugeOpts{
 | 
			
		||||
			Namespace: "go",
 | 
			
		||||
			Name:      "goroutines",
 | 
			
		||||
			Help:      "Number of goroutines that currently exist.",
 | 
			
		||||
		}),
 | 
			
		||||
		goroutinesDesc: NewDesc(
 | 
			
		||||
			"go_goroutines",
 | 
			
		||||
			"Number of goroutines that currently exist.",
 | 
			
		||||
			nil, nil),
 | 
			
		||||
		threadsDesc: NewDesc(
 | 
			
		||||
			"go_threads",
 | 
			
		||||
			"Number of OS threads created",
 | 
			
		||||
			nil, nil),
 | 
			
		||||
		gcDesc: NewDesc(
 | 
			
		||||
			"go_gc_duration_seconds",
 | 
			
		||||
			"A summary of the GC invocation durations.",
 | 
			
		||||
@@ -48,7 +52,7 @@ func NewGoCollector() *goCollector {
 | 
			
		||||
			}, {
 | 
			
		||||
				desc: NewDesc(
 | 
			
		||||
					memstatNamespace("sys_bytes"),
 | 
			
		||||
					"Number of bytes obtained by system. Sum of all system allocations.",
 | 
			
		||||
					"Number of bytes obtained from system.",
 | 
			
		||||
					nil, nil,
 | 
			
		||||
				),
 | 
			
		||||
				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.Sys) },
 | 
			
		||||
@@ -111,12 +115,12 @@ func NewGoCollector() *goCollector {
 | 
			
		||||
				valType: GaugeValue,
 | 
			
		||||
			}, {
 | 
			
		||||
				desc: NewDesc(
 | 
			
		||||
					memstatNamespace("heap_released_bytes_total"),
 | 
			
		||||
					"Total number of heap bytes released to OS.",
 | 
			
		||||
					memstatNamespace("heap_released_bytes"),
 | 
			
		||||
					"Number of heap bytes released to OS.",
 | 
			
		||||
					nil, nil,
 | 
			
		||||
				),
 | 
			
		||||
				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.HeapReleased) },
 | 
			
		||||
				valType: CounterValue,
 | 
			
		||||
				valType: GaugeValue,
 | 
			
		||||
			}, {
 | 
			
		||||
				desc: NewDesc(
 | 
			
		||||
					memstatNamespace("heap_objects"),
 | 
			
		||||
@@ -211,7 +215,15 @@ func NewGoCollector() *goCollector {
 | 
			
		||||
					"Number of seconds since 1970 of last garbage collection.",
 | 
			
		||||
					nil, nil,
 | 
			
		||||
				),
 | 
			
		||||
				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.LastGC*10 ^ 9) },
 | 
			
		||||
				eval:    func(ms *runtime.MemStats) float64 { return float64(ms.LastGC) / 1e9 },
 | 
			
		||||
				valType: GaugeValue,
 | 
			
		||||
			}, {
 | 
			
		||||
				desc: NewDesc(
 | 
			
		||||
					memstatNamespace("gc_cpu_fraction"),
 | 
			
		||||
					"The fraction of this program's available CPU time used by the GC since the program started.",
 | 
			
		||||
					nil, nil,
 | 
			
		||||
				),
 | 
			
		||||
				eval:    func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction },
 | 
			
		||||
				valType: GaugeValue,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -224,9 +236,9 @@ func memstatNamespace(s string) string {
 | 
			
		||||
 | 
			
		||||
// Describe returns all descriptions of the collector.
 | 
			
		||||
func (c *goCollector) Describe(ch chan<- *Desc) {
 | 
			
		||||
	ch <- c.goroutines.Desc()
 | 
			
		||||
	ch <- c.goroutinesDesc
 | 
			
		||||
	ch <- c.threadsDesc
 | 
			
		||||
	ch <- c.gcDesc
 | 
			
		||||
 | 
			
		||||
	for _, i := range c.metrics {
 | 
			
		||||
		ch <- i.desc
 | 
			
		||||
	}
 | 
			
		||||
@@ -234,8 +246,9 @@ func (c *goCollector) Describe(ch chan<- *Desc) {
 | 
			
		||||
 | 
			
		||||
// Collect returns the current state of all metrics of the collector.
 | 
			
		||||
func (c *goCollector) Collect(ch chan<- Metric) {
 | 
			
		||||
	c.goroutines.Set(float64(runtime.NumGoroutine()))
 | 
			
		||||
	ch <- c.goroutines
 | 
			
		||||
	ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine()))
 | 
			
		||||
	n, _ := runtime.ThreadCreateProfile(nil)
 | 
			
		||||
	ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, float64(n))
 | 
			
		||||
 | 
			
		||||
	var stats debug.GCStats
 | 
			
		||||
	stats.PauseQuantiles = make([]time.Duration, 5)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										50
									
								
								vendor/github.com/prometheus/client_golang/prometheus/histogram.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								vendor/github.com/prometheus/client_golang/prometheus/histogram.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -15,7 +15,6 @@ package prometheus
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"hash/fnv"
 | 
			
		||||
	"math"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
@@ -52,11 +51,11 @@ type Histogram interface {
 | 
			
		||||
// bucket of a histogram ("le" -> "less or equal").
 | 
			
		||||
const bucketLabel = "le"
 | 
			
		||||
 | 
			
		||||
// DefBuckets are the default Histogram buckets. The default buckets are
 | 
			
		||||
// tailored to broadly measure the response time (in seconds) of a network
 | 
			
		||||
// service. Most likely, however, you will be required to define buckets
 | 
			
		||||
// customized to your use case.
 | 
			
		||||
var (
 | 
			
		||||
	// DefBuckets are the default Histogram buckets. The default buckets are
 | 
			
		||||
	// tailored to broadly measure the response time (in seconds) of a
 | 
			
		||||
	// network service. Most likely, however, you will be required to define
 | 
			
		||||
	// buckets customized to your use case.
 | 
			
		||||
	DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10}
 | 
			
		||||
 | 
			
		||||
	errBucketLabelNotAllowed = fmt.Errorf(
 | 
			
		||||
@@ -211,7 +210,7 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr
 | 
			
		||||
	// Finally we know the final length of h.upperBounds and can make counts.
 | 
			
		||||
	h.counts = make([]uint64, len(h.upperBounds))
 | 
			
		||||
 | 
			
		||||
	h.Init(h) // Init self-collection.
 | 
			
		||||
	h.init(h) // Init self-collection.
 | 
			
		||||
	return h
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -223,7 +222,7 @@ type histogram struct {
 | 
			
		||||
	sumBits uint64
 | 
			
		||||
	count   uint64
 | 
			
		||||
 | 
			
		||||
	SelfCollector
 | 
			
		||||
	selfCollector
 | 
			
		||||
	// Note that there is no mutex required.
 | 
			
		||||
 | 
			
		||||
	desc *Desc
 | 
			
		||||
@@ -288,7 +287,7 @@ func (h *histogram) Write(out *dto.Metric) error {
 | 
			
		||||
// (e.g. HTTP request latencies, partitioned by status code and method). Create
 | 
			
		||||
// instances with NewHistogramVec.
 | 
			
		||||
type HistogramVec struct {
 | 
			
		||||
	MetricVec
 | 
			
		||||
	*MetricVec
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewHistogramVec creates a new HistogramVec based on the provided HistogramOpts and
 | 
			
		||||
@@ -302,35 +301,30 @@ func NewHistogramVec(opts HistogramOpts, labelNames []string) *HistogramVec {
 | 
			
		||||
		opts.ConstLabels,
 | 
			
		||||
	)
 | 
			
		||||
	return &HistogramVec{
 | 
			
		||||
		MetricVec: MetricVec{
 | 
			
		||||
			children: map[uint64]Metric{},
 | 
			
		||||
			desc:     desc,
 | 
			
		||||
			hash:     fnv.New64a(),
 | 
			
		||||
			newMetric: func(lvs ...string) Metric {
 | 
			
		||||
				return newHistogram(desc, opts, lvs...)
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
 | 
			
		||||
			return newHistogram(desc, opts, lvs...)
 | 
			
		||||
		}),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetMetricWithLabelValues replaces the method of the same name in
 | 
			
		||||
// MetricVec. The difference is that this method returns a Histogram and not a
 | 
			
		||||
// Metric so that no type conversion is required.
 | 
			
		||||
func (m *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Histogram, error) {
 | 
			
		||||
// MetricVec. The difference is that this method returns an Observer and not a
 | 
			
		||||
// Metric so that no type conversion to an Observer is required.
 | 
			
		||||
func (m *HistogramVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
 | 
			
		||||
	metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
 | 
			
		||||
	if metric != nil {
 | 
			
		||||
		return metric.(Histogram), err
 | 
			
		||||
		return metric.(Observer), err
 | 
			
		||||
	}
 | 
			
		||||
	return nil, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetMetricWith replaces the method of the same name in MetricVec. The
 | 
			
		||||
// difference is that this method returns a Histogram and not a Metric so that no
 | 
			
		||||
// type conversion is required.
 | 
			
		||||
func (m *HistogramVec) GetMetricWith(labels Labels) (Histogram, error) {
 | 
			
		||||
// difference is that this method returns an Observer and not a Metric so that no
 | 
			
		||||
// type conversion to an Observer is required.
 | 
			
		||||
func (m *HistogramVec) GetMetricWith(labels Labels) (Observer, error) {
 | 
			
		||||
	metric, err := m.MetricVec.GetMetricWith(labels)
 | 
			
		||||
	if metric != nil {
 | 
			
		||||
		return metric.(Histogram), err
 | 
			
		||||
		return metric.(Observer), err
 | 
			
		||||
	}
 | 
			
		||||
	return nil, err
 | 
			
		||||
}
 | 
			
		||||
@@ -339,15 +333,15 @@ func (m *HistogramVec) GetMetricWith(labels Labels) (Histogram, error) {
 | 
			
		||||
// GetMetricWithLabelValues would have returned an error. By not returning an
 | 
			
		||||
// error, WithLabelValues allows shortcuts like
 | 
			
		||||
//     myVec.WithLabelValues("404", "GET").Observe(42.21)
 | 
			
		||||
func (m *HistogramVec) WithLabelValues(lvs ...string) Histogram {
 | 
			
		||||
	return m.MetricVec.WithLabelValues(lvs...).(Histogram)
 | 
			
		||||
func (m *HistogramVec) WithLabelValues(lvs ...string) Observer {
 | 
			
		||||
	return m.MetricVec.WithLabelValues(lvs...).(Observer)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// With works as GetMetricWith, but panics where GetMetricWithLabels would have
 | 
			
		||||
// returned an error. By not returning an error, With allows shortcuts like
 | 
			
		||||
//     myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
 | 
			
		||||
func (m *HistogramVec) With(labels Labels) Histogram {
 | 
			
		||||
	return m.MetricVec.With(labels).(Histogram)
 | 
			
		||||
func (m *HistogramVec) With(labels Labels) Observer {
 | 
			
		||||
	return m.MetricVec.With(labels).(Observer)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type constHistogram struct {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										243
									
								
								vendor/github.com/prometheus/client_golang/prometheus/http.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										243
									
								
								vendor/github.com/prometheus/client_golang/prometheus/http.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -15,14 +15,115 @@ package prometheus
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"compress/gzip"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/prometheus/common/expfmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TODO(beorn7): Remove this whole file. It is a partial mirror of
 | 
			
		||||
// promhttp/http.go (to avoid circular import chains) where everything HTTP
 | 
			
		||||
// related should live. The functions here are just for avoiding
 | 
			
		||||
// breakage. Everything is deprecated.
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	contentTypeHeader     = "Content-Type"
 | 
			
		||||
	contentLengthHeader   = "Content-Length"
 | 
			
		||||
	contentEncodingHeader = "Content-Encoding"
 | 
			
		||||
	acceptEncodingHeader  = "Accept-Encoding"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var bufPool sync.Pool
 | 
			
		||||
 | 
			
		||||
func getBuf() *bytes.Buffer {
 | 
			
		||||
	buf := bufPool.Get()
 | 
			
		||||
	if buf == nil {
 | 
			
		||||
		return &bytes.Buffer{}
 | 
			
		||||
	}
 | 
			
		||||
	return buf.(*bytes.Buffer)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func giveBuf(buf *bytes.Buffer) {
 | 
			
		||||
	buf.Reset()
 | 
			
		||||
	bufPool.Put(buf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Handler returns an HTTP handler for the DefaultGatherer. It is
 | 
			
		||||
// already instrumented with InstrumentHandler (using "prometheus" as handler
 | 
			
		||||
// name).
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: Please note the issues described in the doc comment of
 | 
			
		||||
// InstrumentHandler. You might want to consider using promhttp.Handler instead
 | 
			
		||||
// (which is not instrumented, but can be instrumented with the tooling provided
 | 
			
		||||
// in package promhttp).
 | 
			
		||||
func Handler() http.Handler {
 | 
			
		||||
	return InstrumentHandler("prometheus", UninstrumentedHandler())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UninstrumentedHandler returns an HTTP handler for the DefaultGatherer.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: Use promhttp.Handler instead. See there for further documentation.
 | 
			
		||||
func UninstrumentedHandler() http.Handler {
 | 
			
		||||
	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		mfs, err := DefaultGatherer.Gather()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			http.Error(w, "An error has occurred during metrics collection:\n\n"+err.Error(), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		contentType := expfmt.Negotiate(req.Header)
 | 
			
		||||
		buf := getBuf()
 | 
			
		||||
		defer giveBuf(buf)
 | 
			
		||||
		writer, encoding := decorateWriter(req, buf)
 | 
			
		||||
		enc := expfmt.NewEncoder(writer, contentType)
 | 
			
		||||
		var lastErr error
 | 
			
		||||
		for _, mf := range mfs {
 | 
			
		||||
			if err := enc.Encode(mf); err != nil {
 | 
			
		||||
				lastErr = err
 | 
			
		||||
				http.Error(w, "An error has occurred during metrics encoding:\n\n"+err.Error(), http.StatusInternalServerError)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if closer, ok := writer.(io.Closer); ok {
 | 
			
		||||
			closer.Close()
 | 
			
		||||
		}
 | 
			
		||||
		if lastErr != nil && buf.Len() == 0 {
 | 
			
		||||
			http.Error(w, "No metrics encoded, last error:\n\n"+err.Error(), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		header := w.Header()
 | 
			
		||||
		header.Set(contentTypeHeader, string(contentType))
 | 
			
		||||
		header.Set(contentLengthHeader, fmt.Sprint(buf.Len()))
 | 
			
		||||
		if encoding != "" {
 | 
			
		||||
			header.Set(contentEncodingHeader, encoding)
 | 
			
		||||
		}
 | 
			
		||||
		w.Write(buf.Bytes())
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// decorateWriter wraps a writer to handle gzip compression if requested.  It
 | 
			
		||||
// returns the decorated writer and the appropriate "Content-Encoding" header
 | 
			
		||||
// (which is empty if no compression is enabled).
 | 
			
		||||
func decorateWriter(request *http.Request, writer io.Writer) (io.Writer, string) {
 | 
			
		||||
	header := request.Header.Get(acceptEncodingHeader)
 | 
			
		||||
	parts := strings.Split(header, ",")
 | 
			
		||||
	for _, part := range parts {
 | 
			
		||||
		part := strings.TrimSpace(part)
 | 
			
		||||
		if part == "gzip" || strings.HasPrefix(part, "gzip;") {
 | 
			
		||||
			return gzip.NewWriter(writer), "gzip"
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return writer, ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var instLabels = []string{"method", "code"}
 | 
			
		||||
 | 
			
		||||
type nower interface {
 | 
			
		||||
@@ -57,29 +158,52 @@ func nowSeries(t ...time.Time) nower {
 | 
			
		||||
// has a constant label named "handler" with the provided handlerName as
 | 
			
		||||
// value. http_requests_total is a metric vector partitioned by HTTP method
 | 
			
		||||
// (label name "method") and HTTP status code (label name "code").
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: InstrumentHandler has several issues. Use the tooling provided in
 | 
			
		||||
// package promhttp instead. The issues are the following:
 | 
			
		||||
//
 | 
			
		||||
// - It uses Summaries rather than Histograms. Summaries are not useful if
 | 
			
		||||
// aggregation across multiple instances is required.
 | 
			
		||||
//
 | 
			
		||||
// - It uses microseconds as unit, which is deprecated and should be replaced by
 | 
			
		||||
// seconds.
 | 
			
		||||
//
 | 
			
		||||
// - The size of the request is calculated in a separate goroutine. Since this
 | 
			
		||||
// calculator requires access to the request header, it creates a race with
 | 
			
		||||
// any writes to the header performed during request handling.
 | 
			
		||||
// httputil.ReverseProxy is a prominent example for a handler
 | 
			
		||||
// performing such writes.
 | 
			
		||||
//
 | 
			
		||||
// - It has additional issues with HTTP/2, cf.
 | 
			
		||||
// https://github.com/prometheus/client_golang/issues/272.
 | 
			
		||||
func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFunc {
 | 
			
		||||
	return InstrumentHandlerFunc(handlerName, handler.ServeHTTP)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentHandlerFunc wraps the given function for instrumentation. It
 | 
			
		||||
// otherwise works in the same way as InstrumentHandler.
 | 
			
		||||
// otherwise works in the same way as InstrumentHandler (and shares the same
 | 
			
		||||
// issues).
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: InstrumentHandlerFunc is deprecated for the same reasons as
 | 
			
		||||
// InstrumentHandler is. Use the tooling provided in package promhttp instead.
 | 
			
		||||
func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
 | 
			
		||||
	return InstrumentHandlerFuncWithOpts(
 | 
			
		||||
		SummaryOpts{
 | 
			
		||||
			Subsystem:   "http",
 | 
			
		||||
			ConstLabels: Labels{"handler": handlerName},
 | 
			
		||||
			Objectives:  map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
 | 
			
		||||
		},
 | 
			
		||||
		handlerFunc,
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentHandlerWithOpts works like InstrumentHandler but provides more
 | 
			
		||||
// flexibility (at the cost of a more complex call syntax). As
 | 
			
		||||
// InstrumentHandler, this function registers four metric collectors, but it
 | 
			
		||||
// uses the provided SummaryOpts to create them. However, the fields "Name" and
 | 
			
		||||
// "Help" in the SummaryOpts are ignored. "Name" is replaced by
 | 
			
		||||
// "requests_total", "request_duration_microseconds", "request_size_bytes", and
 | 
			
		||||
// "response_size_bytes", respectively. "Help" is replaced by an appropriate
 | 
			
		||||
// InstrumentHandlerWithOpts works like InstrumentHandler (and shares the same
 | 
			
		||||
// issues) but provides more flexibility (at the cost of a more complex call
 | 
			
		||||
// syntax). As InstrumentHandler, this function registers four metric
 | 
			
		||||
// collectors, but it uses the provided SummaryOpts to create them. However, the
 | 
			
		||||
// fields "Name" and "Help" in the SummaryOpts are ignored. "Name" is replaced
 | 
			
		||||
// by "requests_total", "request_duration_microseconds", "request_size_bytes",
 | 
			
		||||
// and "response_size_bytes", respectively. "Help" is replaced by an appropriate
 | 
			
		||||
// help string. The names of the variable labels of the http_requests_total
 | 
			
		||||
// CounterVec are "method" (get, post, etc.), and "code" (HTTP status code).
 | 
			
		||||
//
 | 
			
		||||
@@ -98,13 +222,20 @@ func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWri
 | 
			
		||||
// cannot use SummaryOpts. Instead, a CounterOpts struct is created internally,
 | 
			
		||||
// and all its fields are set to the equally named fields in the provided
 | 
			
		||||
// SummaryOpts.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: InstrumentHandlerWithOpts is deprecated for the same reasons as
 | 
			
		||||
// InstrumentHandler is. Use the tooling provided in package promhttp instead.
 | 
			
		||||
func InstrumentHandlerWithOpts(opts SummaryOpts, handler http.Handler) http.HandlerFunc {
 | 
			
		||||
	return InstrumentHandlerFuncWithOpts(opts, handler.ServeHTTP)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentHandlerFuncWithOpts works like InstrumentHandlerFunc but provides
 | 
			
		||||
// more flexibility (at the cost of a more complex call syntax). See
 | 
			
		||||
// InstrumentHandlerWithOpts for details how the provided SummaryOpts are used.
 | 
			
		||||
// InstrumentHandlerFuncWithOpts works like InstrumentHandlerFunc (and shares
 | 
			
		||||
// the same issues) but provides more flexibility (at the cost of a more complex
 | 
			
		||||
// call syntax). See InstrumentHandlerWithOpts for details how the provided
 | 
			
		||||
// SummaryOpts are used.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: InstrumentHandlerFuncWithOpts is deprecated for the same reasons
 | 
			
		||||
// as InstrumentHandler is. Use the tooling provided in package promhttp instead.
 | 
			
		||||
func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
 | 
			
		||||
	reqCnt := NewCounterVec(
 | 
			
		||||
		CounterOpts{
 | 
			
		||||
@@ -116,34 +247,52 @@ func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.Respo
 | 
			
		||||
		},
 | 
			
		||||
		instLabels,
 | 
			
		||||
	)
 | 
			
		||||
	if err := Register(reqCnt); err != nil {
 | 
			
		||||
		if are, ok := err.(AlreadyRegisteredError); ok {
 | 
			
		||||
			reqCnt = are.ExistingCollector.(*CounterVec)
 | 
			
		||||
		} else {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opts.Name = "request_duration_microseconds"
 | 
			
		||||
	opts.Help = "The HTTP request latencies in microseconds."
 | 
			
		||||
	reqDur := NewSummary(opts)
 | 
			
		||||
	if err := Register(reqDur); err != nil {
 | 
			
		||||
		if are, ok := err.(AlreadyRegisteredError); ok {
 | 
			
		||||
			reqDur = are.ExistingCollector.(Summary)
 | 
			
		||||
		} else {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opts.Name = "request_size_bytes"
 | 
			
		||||
	opts.Help = "The HTTP request sizes in bytes."
 | 
			
		||||
	reqSz := NewSummary(opts)
 | 
			
		||||
	if err := Register(reqSz); err != nil {
 | 
			
		||||
		if are, ok := err.(AlreadyRegisteredError); ok {
 | 
			
		||||
			reqSz = are.ExistingCollector.(Summary)
 | 
			
		||||
		} else {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opts.Name = "response_size_bytes"
 | 
			
		||||
	opts.Help = "The HTTP response sizes in bytes."
 | 
			
		||||
	resSz := NewSummary(opts)
 | 
			
		||||
 | 
			
		||||
	regReqCnt := MustRegisterOrGet(reqCnt).(*CounterVec)
 | 
			
		||||
	regReqDur := MustRegisterOrGet(reqDur).(Summary)
 | 
			
		||||
	regReqSz := MustRegisterOrGet(reqSz).(Summary)
 | 
			
		||||
	regResSz := MustRegisterOrGet(resSz).(Summary)
 | 
			
		||||
	if err := Register(resSz); err != nil {
 | 
			
		||||
		if are, ok := err.(AlreadyRegisteredError); ok {
 | 
			
		||||
			resSz = are.ExistingCollector.(Summary)
 | 
			
		||||
		} else {
 | 
			
		||||
			panic(err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		now := time.Now()
 | 
			
		||||
 | 
			
		||||
		delegate := &responseWriterDelegator{ResponseWriter: w}
 | 
			
		||||
		out := make(chan int)
 | 
			
		||||
		urlLen := 0
 | 
			
		||||
		if r.URL != nil {
 | 
			
		||||
			urlLen = len(r.URL.String())
 | 
			
		||||
		}
 | 
			
		||||
		go computeApproximateRequestSize(r, out, urlLen)
 | 
			
		||||
		out := computeApproximateRequestSize(r)
 | 
			
		||||
 | 
			
		||||
		_, cn := w.(http.CloseNotifier)
 | 
			
		||||
		_, fl := w.(http.Flusher)
 | 
			
		||||
@@ -161,30 +310,44 @@ func InstrumentHandlerFuncWithOpts(opts SummaryOpts, handlerFunc func(http.Respo
 | 
			
		||||
 | 
			
		||||
		method := sanitizeMethod(r.Method)
 | 
			
		||||
		code := sanitizeCode(delegate.status)
 | 
			
		||||
		regReqCnt.WithLabelValues(method, code).Inc()
 | 
			
		||||
		regReqDur.Observe(elapsed)
 | 
			
		||||
		regResSz.Observe(float64(delegate.written))
 | 
			
		||||
		regReqSz.Observe(float64(<-out))
 | 
			
		||||
		reqCnt.WithLabelValues(method, code).Inc()
 | 
			
		||||
		reqDur.Observe(elapsed)
 | 
			
		||||
		resSz.Observe(float64(delegate.written))
 | 
			
		||||
		reqSz.Observe(float64(<-out))
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func computeApproximateRequestSize(r *http.Request, out chan int, s int) {
 | 
			
		||||
	s += len(r.Method)
 | 
			
		||||
	s += len(r.Proto)
 | 
			
		||||
	for name, values := range r.Header {
 | 
			
		||||
		s += len(name)
 | 
			
		||||
		for _, value := range values {
 | 
			
		||||
			s += len(value)
 | 
			
		||||
func computeApproximateRequestSize(r *http.Request) <-chan int {
 | 
			
		||||
	// Get URL length in current go routine for avoiding a race condition.
 | 
			
		||||
	// HandlerFunc that runs in parallel may modify the URL.
 | 
			
		||||
	s := 0
 | 
			
		||||
	if r.URL != nil {
 | 
			
		||||
		s += len(r.URL.String())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	out := make(chan int, 1)
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		s += len(r.Method)
 | 
			
		||||
		s += len(r.Proto)
 | 
			
		||||
		for name, values := range r.Header {
 | 
			
		||||
			s += len(name)
 | 
			
		||||
			for _, value := range values {
 | 
			
		||||
				s += len(value)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	s += len(r.Host)
 | 
			
		||||
		s += len(r.Host)
 | 
			
		||||
 | 
			
		||||
	// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
 | 
			
		||||
		// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
 | 
			
		||||
 | 
			
		||||
	if r.ContentLength != -1 {
 | 
			
		||||
		s += int(r.ContentLength)
 | 
			
		||||
	}
 | 
			
		||||
	out <- s
 | 
			
		||||
		if r.ContentLength != -1 {
 | 
			
		||||
			s += int(r.ContentLength)
 | 
			
		||||
		}
 | 
			
		||||
		out <- s
 | 
			
		||||
		close(out)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type responseWriterDelegator struct {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								vendor/github.com/prometheus/client_golang/prometheus/metric.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/prometheus/client_golang/prometheus/metric.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -22,10 +22,8 @@ import (
 | 
			
		||||
const separatorByte byte = 255
 | 
			
		||||
 | 
			
		||||
// A Metric models a single sample value with its meta data being exported to
 | 
			
		||||
// Prometheus. Implementers of Metric in this package inclued Gauge, Counter,
 | 
			
		||||
// Untyped, and Summary. Users can implement their own Metric types, but that
 | 
			
		||||
// should be rarely needed. See the example for SelfCollector, which is also an
 | 
			
		||||
// example for a user-implemented Metric.
 | 
			
		||||
// Prometheus. Implementations of Metric in this package are Gauge, Counter,
 | 
			
		||||
// Histogram, Summary, and Untyped.
 | 
			
		||||
type Metric interface {
 | 
			
		||||
	// Desc returns the descriptor for the Metric. This method idempotently
 | 
			
		||||
	// returns the same descriptor throughout the lifetime of the
 | 
			
		||||
@@ -36,21 +34,23 @@ type Metric interface {
 | 
			
		||||
	// Write encodes the Metric into a "Metric" Protocol Buffer data
 | 
			
		||||
	// transmission object.
 | 
			
		||||
	//
 | 
			
		||||
	// Implementers of custom Metric types must observe concurrency safety
 | 
			
		||||
	// as reads of this metric may occur at any time, and any blocking
 | 
			
		||||
	// occurs at the expense of total performance of rendering all
 | 
			
		||||
	// registered metrics. Ideally Metric implementations should support
 | 
			
		||||
	// concurrent readers.
 | 
			
		||||
	// Metric implementations must observe concurrency safety as reads of
 | 
			
		||||
	// this metric may occur at any time, and any blocking occurs at the
 | 
			
		||||
	// expense of total performance of rendering all registered
 | 
			
		||||
	// metrics. Ideally, Metric implementations should support concurrent
 | 
			
		||||
	// readers.
 | 
			
		||||
	//
 | 
			
		||||
	// The Prometheus client library attempts to minimize memory allocations
 | 
			
		||||
	// and will provide a pre-existing reset dto.Metric pointer. Prometheus
 | 
			
		||||
	// may recycle the dto.Metric proto message, so Metric implementations
 | 
			
		||||
	// should just populate the provided dto.Metric and then should not keep
 | 
			
		||||
	// any reference to it.
 | 
			
		||||
	//
 | 
			
		||||
	// While populating dto.Metric, labels must be sorted lexicographically.
 | 
			
		||||
	// (Implementers may find LabelPairSorter useful for that.)
 | 
			
		||||
	// While populating dto.Metric, it is the responsibility of the
 | 
			
		||||
	// implementation to ensure validity of the Metric protobuf (like valid
 | 
			
		||||
	// UTF-8 strings or syntactically valid metric and label names). It is
 | 
			
		||||
	// recommended to sort labels lexicographically. (Implementers may find
 | 
			
		||||
	// LabelPairSorter useful for that.) Callers of Write should still make
 | 
			
		||||
	// sure of sorting if they depend on it.
 | 
			
		||||
	Write(*dto.Metric) error
 | 
			
		||||
	// TODO(beorn7): The original rationale of passing in a pre-allocated
 | 
			
		||||
	// dto.Metric protobuf to save allocations has disappeared. The
 | 
			
		||||
	// signature of this method should be changed to "Write() (*dto.Metric,
 | 
			
		||||
	// error)".
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Opts bundles the options for creating most Metric types. Each metric
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										50
									
								
								vendor/github.com/prometheus/client_golang/prometheus/observer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								vendor/github.com/prometheus/client_golang/prometheus/observer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
// Copyright 2017 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package prometheus
 | 
			
		||||
 | 
			
		||||
// Observer is the interface that wraps the Observe method, which is used by
 | 
			
		||||
// Histogram and Summary to add observations.
 | 
			
		||||
type Observer interface {
 | 
			
		||||
	Observe(float64)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The ObserverFunc type is an adapter to allow the use of ordinary
 | 
			
		||||
// functions as Observers. If f is a function with the appropriate
 | 
			
		||||
// signature, ObserverFunc(f) is an Observer that calls f.
 | 
			
		||||
//
 | 
			
		||||
// This adapter is usually used in connection with the Timer type, and there are
 | 
			
		||||
// two general use cases:
 | 
			
		||||
//
 | 
			
		||||
// The most common one is to use a Gauge as the Observer for a Timer.
 | 
			
		||||
// See the "Gauge" Timer example.
 | 
			
		||||
//
 | 
			
		||||
// The more advanced use case is to create a function that dynamically decides
 | 
			
		||||
// which Observer to use for observing the duration. See the "Complex" Timer
 | 
			
		||||
// example.
 | 
			
		||||
type ObserverFunc func(float64)
 | 
			
		||||
 | 
			
		||||
// Observe calls f(value). It implements Observer.
 | 
			
		||||
func (f ObserverFunc) Observe(value float64) {
 | 
			
		||||
	f(value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ObserverVec is an interface implemented by `HistogramVec` and `SummaryVec`.
 | 
			
		||||
type ObserverVec interface {
 | 
			
		||||
	GetMetricWith(Labels) (Observer, error)
 | 
			
		||||
	GetMetricWithLabelValues(lvs ...string) (Observer, error)
 | 
			
		||||
	With(Labels) Observer
 | 
			
		||||
	WithLabelValues(...string) Observer
 | 
			
		||||
 | 
			
		||||
	Collector
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										108
									
								
								vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										108
									
								
								vendor/github.com/prometheus/client_golang/prometheus/process_collector.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -19,16 +19,16 @@ type processCollector struct {
 | 
			
		||||
	pid             int
 | 
			
		||||
	collectFn       func(chan<- Metric)
 | 
			
		||||
	pidFn           func() (int, error)
 | 
			
		||||
	cpuTotal        Counter
 | 
			
		||||
	openFDs, maxFDs Gauge
 | 
			
		||||
	vsize, rss      Gauge
 | 
			
		||||
	startTime       Gauge
 | 
			
		||||
	cpuTotal        *Desc
 | 
			
		||||
	openFDs, maxFDs *Desc
 | 
			
		||||
	vsize, rss      *Desc
 | 
			
		||||
	startTime       *Desc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewProcessCollector returns a collector which exports the current state of
 | 
			
		||||
// process metrics including cpu, memory and file descriptor usage as well as
 | 
			
		||||
// the process start time for the given process id under the given namespace.
 | 
			
		||||
func NewProcessCollector(pid int, namespace string) *processCollector {
 | 
			
		||||
func NewProcessCollector(pid int, namespace string) Collector {
 | 
			
		||||
	return NewProcessCollectorPIDFn(
 | 
			
		||||
		func() (int, error) { return pid, nil },
 | 
			
		||||
		namespace,
 | 
			
		||||
@@ -43,41 +43,46 @@ func NewProcessCollector(pid int, namespace string) *processCollector {
 | 
			
		||||
func NewProcessCollectorPIDFn(
 | 
			
		||||
	pidFn func() (int, error),
 | 
			
		||||
	namespace string,
 | 
			
		||||
) *processCollector {
 | 
			
		||||
) Collector {
 | 
			
		||||
	ns := ""
 | 
			
		||||
	if len(namespace) > 0 {
 | 
			
		||||
		ns = namespace + "_"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c := processCollector{
 | 
			
		||||
		pidFn:     pidFn,
 | 
			
		||||
		collectFn: func(chan<- Metric) {},
 | 
			
		||||
 | 
			
		||||
		cpuTotal: NewCounter(CounterOpts{
 | 
			
		||||
			Namespace: namespace,
 | 
			
		||||
			Name:      "process_cpu_seconds_total",
 | 
			
		||||
			Help:      "Total user and system CPU time spent in seconds.",
 | 
			
		||||
		}),
 | 
			
		||||
		openFDs: NewGauge(GaugeOpts{
 | 
			
		||||
			Namespace: namespace,
 | 
			
		||||
			Name:      "process_open_fds",
 | 
			
		||||
			Help:      "Number of open file descriptors.",
 | 
			
		||||
		}),
 | 
			
		||||
		maxFDs: NewGauge(GaugeOpts{
 | 
			
		||||
			Namespace: namespace,
 | 
			
		||||
			Name:      "process_max_fds",
 | 
			
		||||
			Help:      "Maximum number of open file descriptors.",
 | 
			
		||||
		}),
 | 
			
		||||
		vsize: NewGauge(GaugeOpts{
 | 
			
		||||
			Namespace: namespace,
 | 
			
		||||
			Name:      "process_virtual_memory_bytes",
 | 
			
		||||
			Help:      "Virtual memory size in bytes.",
 | 
			
		||||
		}),
 | 
			
		||||
		rss: NewGauge(GaugeOpts{
 | 
			
		||||
			Namespace: namespace,
 | 
			
		||||
			Name:      "process_resident_memory_bytes",
 | 
			
		||||
			Help:      "Resident memory size in bytes.",
 | 
			
		||||
		}),
 | 
			
		||||
		startTime: NewGauge(GaugeOpts{
 | 
			
		||||
			Namespace: namespace,
 | 
			
		||||
			Name:      "process_start_time_seconds",
 | 
			
		||||
			Help:      "Start time of the process since unix epoch in seconds.",
 | 
			
		||||
		}),
 | 
			
		||||
		cpuTotal: NewDesc(
 | 
			
		||||
			ns+"process_cpu_seconds_total",
 | 
			
		||||
			"Total user and system CPU time spent in seconds.",
 | 
			
		||||
			nil, nil,
 | 
			
		||||
		),
 | 
			
		||||
		openFDs: NewDesc(
 | 
			
		||||
			ns+"process_open_fds",
 | 
			
		||||
			"Number of open file descriptors.",
 | 
			
		||||
			nil, nil,
 | 
			
		||||
		),
 | 
			
		||||
		maxFDs: NewDesc(
 | 
			
		||||
			ns+"process_max_fds",
 | 
			
		||||
			"Maximum number of open file descriptors.",
 | 
			
		||||
			nil, nil,
 | 
			
		||||
		),
 | 
			
		||||
		vsize: NewDesc(
 | 
			
		||||
			ns+"process_virtual_memory_bytes",
 | 
			
		||||
			"Virtual memory size in bytes.",
 | 
			
		||||
			nil, nil,
 | 
			
		||||
		),
 | 
			
		||||
		rss: NewDesc(
 | 
			
		||||
			ns+"process_resident_memory_bytes",
 | 
			
		||||
			"Resident memory size in bytes.",
 | 
			
		||||
			nil, nil,
 | 
			
		||||
		),
 | 
			
		||||
		startTime: NewDesc(
 | 
			
		||||
			ns+"process_start_time_seconds",
 | 
			
		||||
			"Start time of the process since unix epoch in seconds.",
 | 
			
		||||
			nil, nil,
 | 
			
		||||
		),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Set up process metric collection if supported by the runtime.
 | 
			
		||||
@@ -90,12 +95,12 @@ func NewProcessCollectorPIDFn(
 | 
			
		||||
 | 
			
		||||
// Describe returns all descriptions of the collector.
 | 
			
		||||
func (c *processCollector) Describe(ch chan<- *Desc) {
 | 
			
		||||
	ch <- c.cpuTotal.Desc()
 | 
			
		||||
	ch <- c.openFDs.Desc()
 | 
			
		||||
	ch <- c.maxFDs.Desc()
 | 
			
		||||
	ch <- c.vsize.Desc()
 | 
			
		||||
	ch <- c.rss.Desc()
 | 
			
		||||
	ch <- c.startTime.Desc()
 | 
			
		||||
	ch <- c.cpuTotal
 | 
			
		||||
	ch <- c.openFDs
 | 
			
		||||
	ch <- c.maxFDs
 | 
			
		||||
	ch <- c.vsize
 | 
			
		||||
	ch <- c.rss
 | 
			
		||||
	ch <- c.startTime
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Collect returns the current state of all metrics of the collector.
 | 
			
		||||
@@ -117,26 +122,19 @@ func (c *processCollector) processCollect(ch chan<- Metric) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if stat, err := p.NewStat(); err == nil {
 | 
			
		||||
		c.cpuTotal.Set(stat.CPUTime())
 | 
			
		||||
		ch <- c.cpuTotal
 | 
			
		||||
		c.vsize.Set(float64(stat.VirtualMemory()))
 | 
			
		||||
		ch <- c.vsize
 | 
			
		||||
		c.rss.Set(float64(stat.ResidentMemory()))
 | 
			
		||||
		ch <- c.rss
 | 
			
		||||
 | 
			
		||||
		ch <- MustNewConstMetric(c.cpuTotal, CounterValue, stat.CPUTime())
 | 
			
		||||
		ch <- MustNewConstMetric(c.vsize, GaugeValue, float64(stat.VirtualMemory()))
 | 
			
		||||
		ch <- MustNewConstMetric(c.rss, GaugeValue, float64(stat.ResidentMemory()))
 | 
			
		||||
		if startTime, err := stat.StartTime(); err == nil {
 | 
			
		||||
			c.startTime.Set(startTime)
 | 
			
		||||
			ch <- c.startTime
 | 
			
		||||
			ch <- MustNewConstMetric(c.startTime, GaugeValue, startTime)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if fds, err := p.FileDescriptorsLen(); err == nil {
 | 
			
		||||
		c.openFDs.Set(float64(fds))
 | 
			
		||||
		ch <- c.openFDs
 | 
			
		||||
		ch <- MustNewConstMetric(c.openFDs, GaugeValue, float64(fds))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if limits, err := p.NewLimits(); err == nil {
 | 
			
		||||
		c.maxFDs.Set(float64(limits.OpenFiles))
 | 
			
		||||
		ch <- c.maxFDs
 | 
			
		||||
		ch <- MustNewConstMetric(c.maxFDs, GaugeValue, float64(limits.OpenFiles))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
package(default_visibility = ["//visibility:public"])
 | 
			
		||||
 | 
			
		||||
licenses(["notice"])
 | 
			
		||||
 | 
			
		||||
load(
 | 
			
		||||
    "@io_bazel_rules_go//go:def.bzl",
 | 
			
		||||
    "go_library",
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "delegator_1_8.go",
 | 
			
		||||
        "http.go",
 | 
			
		||||
        "instrument_client.go",
 | 
			
		||||
        "instrument_client_1_8.go",
 | 
			
		||||
        "instrument_server.go",
 | 
			
		||||
    ],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
 | 
			
		||||
        "//vendor/github.com/prometheus/client_model/go:go_default_library",
 | 
			
		||||
        "//vendor/github.com/prometheus/common/expfmt:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
    name = "package-srcs",
 | 
			
		||||
    srcs = glob(["**"]),
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    visibility = ["//visibility:private"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
    name = "all-srcs",
 | 
			
		||||
    srcs = [":package-srcs"],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										38
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_7.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
// Copyright 2017 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// +build !go1.8
 | 
			
		||||
 | 
			
		||||
package promhttp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
 | 
			
		||||
	d := &responseWriterDelegator{
 | 
			
		||||
		ResponseWriter:     w,
 | 
			
		||||
		observeWriteHeader: observeWriteHeaderFunc,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, cn := w.(http.CloseNotifier)
 | 
			
		||||
	_, fl := w.(http.Flusher)
 | 
			
		||||
	_, hj := w.(http.Hijacker)
 | 
			
		||||
	_, rf := w.(io.ReaderFrom)
 | 
			
		||||
	if cn && fl && hj && rf {
 | 
			
		||||
		return &fancyDelegator{d}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return d
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator_1_8.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
// Copyright 2017 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// +build go1.8
 | 
			
		||||
 | 
			
		||||
package promhttp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// newDelegator handles the four different methods of upgrading a
 | 
			
		||||
// http.ResponseWriter to delegator.
 | 
			
		||||
func newDelegator(w http.ResponseWriter, observeWriteHeaderFunc func(int)) delegator {
 | 
			
		||||
	d := &responseWriterDelegator{
 | 
			
		||||
		ResponseWriter:     w,
 | 
			
		||||
		observeWriteHeader: observeWriteHeaderFunc,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, cn := w.(http.CloseNotifier)
 | 
			
		||||
	_, fl := w.(http.Flusher)
 | 
			
		||||
	_, hj := w.(http.Hijacker)
 | 
			
		||||
	_, ps := w.(http.Pusher)
 | 
			
		||||
	_, rf := w.(io.ReaderFrom)
 | 
			
		||||
 | 
			
		||||
	// Check for the four most common combination of interfaces a
 | 
			
		||||
	// http.ResponseWriter might implement.
 | 
			
		||||
	switch {
 | 
			
		||||
	case cn && fl && hj && rf && ps:
 | 
			
		||||
		// All interfaces.
 | 
			
		||||
		return &fancyPushDelegator{
 | 
			
		||||
			fancyDelegator: &fancyDelegator{d},
 | 
			
		||||
			p:              &pushDelegator{d},
 | 
			
		||||
		}
 | 
			
		||||
	case cn && fl && hj && rf:
 | 
			
		||||
		// All interfaces, except http.Pusher.
 | 
			
		||||
		return &fancyDelegator{d}
 | 
			
		||||
	case ps:
 | 
			
		||||
		// Just http.Pusher.
 | 
			
		||||
		return &pushDelegator{d}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return d
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type fancyPushDelegator struct {
 | 
			
		||||
	p *pushDelegator
 | 
			
		||||
 | 
			
		||||
	*fancyDelegator
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *fancyPushDelegator) Push(target string, opts *http.PushOptions) error {
 | 
			
		||||
	return f.p.Push(target, opts)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type pushDelegator struct {
 | 
			
		||||
	*responseWriterDelegator
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *pushDelegator) Push(target string, opts *http.PushOptions) error {
 | 
			
		||||
	return f.ResponseWriter.(http.Pusher).Push(target, opts)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										204
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,204 @@
 | 
			
		||||
// Copyright 2016 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// Package promhttp provides tooling around HTTP servers and clients.
 | 
			
		||||
//
 | 
			
		||||
// First, the package allows the creation of http.Handler instances to expose
 | 
			
		||||
// Prometheus metrics via HTTP. promhttp.Handler acts on the
 | 
			
		||||
// prometheus.DefaultGatherer. With HandlerFor, you can create a handler for a
 | 
			
		||||
// custom registry or anything that implements the Gatherer interface. It also
 | 
			
		||||
// allows the creation of handlers that act differently on errors or allow to
 | 
			
		||||
// log errors.
 | 
			
		||||
//
 | 
			
		||||
// Second, the package provides tooling to instrument instances of http.Handler
 | 
			
		||||
// via middleware. Middleware wrappers follow the naming scheme
 | 
			
		||||
// InstrumentHandlerX, where X describes the intended use of the middleware.
 | 
			
		||||
// See each function's doc comment for specific details.
 | 
			
		||||
//
 | 
			
		||||
// Finally, the package allows for an http.RoundTripper to be instrumented via
 | 
			
		||||
// middleware. Middleware wrappers follow the naming scheme
 | 
			
		||||
// InstrumentRoundTripperX, where X describes the intended use of the
 | 
			
		||||
// middleware. See each function's doc comment for specific details.
 | 
			
		||||
package promhttp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"compress/gzip"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"github.com/prometheus/common/expfmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/prometheus/client_golang/prometheus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	contentTypeHeader     = "Content-Type"
 | 
			
		||||
	contentLengthHeader   = "Content-Length"
 | 
			
		||||
	contentEncodingHeader = "Content-Encoding"
 | 
			
		||||
	acceptEncodingHeader  = "Accept-Encoding"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var bufPool sync.Pool
 | 
			
		||||
 | 
			
		||||
func getBuf() *bytes.Buffer {
 | 
			
		||||
	buf := bufPool.Get()
 | 
			
		||||
	if buf == nil {
 | 
			
		||||
		return &bytes.Buffer{}
 | 
			
		||||
	}
 | 
			
		||||
	return buf.(*bytes.Buffer)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func giveBuf(buf *bytes.Buffer) {
 | 
			
		||||
	buf.Reset()
 | 
			
		||||
	bufPool.Put(buf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Handler returns an HTTP handler for the prometheus.DefaultGatherer. The
 | 
			
		||||
// Handler uses the default HandlerOpts, i.e. report the first error as an HTTP
 | 
			
		||||
// error, no error logging, and compression if requested by the client.
 | 
			
		||||
//
 | 
			
		||||
// If you want to create a Handler for the DefaultGatherer with different
 | 
			
		||||
// HandlerOpts, create it with HandlerFor with prometheus.DefaultGatherer and
 | 
			
		||||
// your desired HandlerOpts.
 | 
			
		||||
func Handler() http.Handler {
 | 
			
		||||
	return HandlerFor(prometheus.DefaultGatherer, HandlerOpts{})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HandlerFor returns an http.Handler for the provided Gatherer. The behavior
 | 
			
		||||
// of the Handler is defined by the provided HandlerOpts.
 | 
			
		||||
func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
 | 
			
		||||
	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		mfs, err := reg.Gather()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if opts.ErrorLog != nil {
 | 
			
		||||
				opts.ErrorLog.Println("error gathering metrics:", err)
 | 
			
		||||
			}
 | 
			
		||||
			switch opts.ErrorHandling {
 | 
			
		||||
			case PanicOnError:
 | 
			
		||||
				panic(err)
 | 
			
		||||
			case ContinueOnError:
 | 
			
		||||
				if len(mfs) == 0 {
 | 
			
		||||
					http.Error(w, "No metrics gathered, last error:\n\n"+err.Error(), http.StatusInternalServerError)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
			case HTTPErrorOnError:
 | 
			
		||||
				http.Error(w, "An error has occurred during metrics gathering:\n\n"+err.Error(), http.StatusInternalServerError)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		contentType := expfmt.Negotiate(req.Header)
 | 
			
		||||
		buf := getBuf()
 | 
			
		||||
		defer giveBuf(buf)
 | 
			
		||||
		writer, encoding := decorateWriter(req, buf, opts.DisableCompression)
 | 
			
		||||
		enc := expfmt.NewEncoder(writer, contentType)
 | 
			
		||||
		var lastErr error
 | 
			
		||||
		for _, mf := range mfs {
 | 
			
		||||
			if err := enc.Encode(mf); err != nil {
 | 
			
		||||
				lastErr = err
 | 
			
		||||
				if opts.ErrorLog != nil {
 | 
			
		||||
					opts.ErrorLog.Println("error encoding metric family:", err)
 | 
			
		||||
				}
 | 
			
		||||
				switch opts.ErrorHandling {
 | 
			
		||||
				case PanicOnError:
 | 
			
		||||
					panic(err)
 | 
			
		||||
				case ContinueOnError:
 | 
			
		||||
					// Handled later.
 | 
			
		||||
				case HTTPErrorOnError:
 | 
			
		||||
					http.Error(w, "An error has occurred during metrics encoding:\n\n"+err.Error(), http.StatusInternalServerError)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if closer, ok := writer.(io.Closer); ok {
 | 
			
		||||
			closer.Close()
 | 
			
		||||
		}
 | 
			
		||||
		if lastErr != nil && buf.Len() == 0 {
 | 
			
		||||
			http.Error(w, "No metrics encoded, last error:\n\n"+err.Error(), http.StatusInternalServerError)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		header := w.Header()
 | 
			
		||||
		header.Set(contentTypeHeader, string(contentType))
 | 
			
		||||
		header.Set(contentLengthHeader, fmt.Sprint(buf.Len()))
 | 
			
		||||
		if encoding != "" {
 | 
			
		||||
			header.Set(contentEncodingHeader, encoding)
 | 
			
		||||
		}
 | 
			
		||||
		w.Write(buf.Bytes())
 | 
			
		||||
		// TODO(beorn7): Consider streaming serving of metrics.
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HandlerErrorHandling defines how a Handler serving metrics will handle
 | 
			
		||||
// errors.
 | 
			
		||||
type HandlerErrorHandling int
 | 
			
		||||
 | 
			
		||||
// These constants cause handlers serving metrics to behave as described if
 | 
			
		||||
// errors are encountered.
 | 
			
		||||
const (
 | 
			
		||||
	// Serve an HTTP status code 500 upon the first error
 | 
			
		||||
	// encountered. Report the error message in the body.
 | 
			
		||||
	HTTPErrorOnError HandlerErrorHandling = iota
 | 
			
		||||
	// Ignore errors and try to serve as many metrics as possible.  However,
 | 
			
		||||
	// if no metrics can be served, serve an HTTP status code 500 and the
 | 
			
		||||
	// last error message in the body. Only use this in deliberate "best
 | 
			
		||||
	// effort" metrics collection scenarios. It is recommended to at least
 | 
			
		||||
	// log errors (by providing an ErrorLog in HandlerOpts) to not mask
 | 
			
		||||
	// errors completely.
 | 
			
		||||
	ContinueOnError
 | 
			
		||||
	// Panic upon the first error encountered (useful for "crash only" apps).
 | 
			
		||||
	PanicOnError
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Logger is the minimal interface HandlerOpts needs for logging. Note that
 | 
			
		||||
// log.Logger from the standard library implements this interface, and it is
 | 
			
		||||
// easy to implement by custom loggers, if they don't do so already anyway.
 | 
			
		||||
type Logger interface {
 | 
			
		||||
	Println(v ...interface{})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HandlerOpts specifies options how to serve metrics via an http.Handler. The
 | 
			
		||||
// zero value of HandlerOpts is a reasonable default.
 | 
			
		||||
type HandlerOpts struct {
 | 
			
		||||
	// ErrorLog specifies an optional logger for errors collecting and
 | 
			
		||||
	// serving metrics. If nil, errors are not logged at all.
 | 
			
		||||
	ErrorLog Logger
 | 
			
		||||
	// ErrorHandling defines how errors are handled. Note that errors are
 | 
			
		||||
	// logged regardless of the configured ErrorHandling provided ErrorLog
 | 
			
		||||
	// is not nil.
 | 
			
		||||
	ErrorHandling HandlerErrorHandling
 | 
			
		||||
	// If DisableCompression is true, the handler will never compress the
 | 
			
		||||
	// response, even if requested by the client.
 | 
			
		||||
	DisableCompression bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// decorateWriter wraps a writer to handle gzip compression if requested.  It
 | 
			
		||||
// returns the decorated writer and the appropriate "Content-Encoding" header
 | 
			
		||||
// (which is empty if no compression is enabled).
 | 
			
		||||
func decorateWriter(request *http.Request, writer io.Writer, compressionDisabled bool) (io.Writer, string) {
 | 
			
		||||
	if compressionDisabled {
 | 
			
		||||
		return writer, ""
 | 
			
		||||
	}
 | 
			
		||||
	header := request.Header.Get(acceptEncodingHeader)
 | 
			
		||||
	parts := strings.Split(header, ",")
 | 
			
		||||
	for _, part := range parts {
 | 
			
		||||
		part := strings.TrimSpace(part)
 | 
			
		||||
		if part == "gzip" || strings.HasPrefix(part, "gzip;") {
 | 
			
		||||
			return gzip.NewWriter(writer), "gzip"
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return writer, ""
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										95
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
// Copyright 2017 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package promhttp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/prometheus/client_golang/prometheus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// The RoundTripperFunc type is an adapter to allow the use of ordinary
 | 
			
		||||
// functions as RoundTrippers. If f is a function with the appropriate
 | 
			
		||||
// signature, RountTripperFunc(f) is a RoundTripper that calls f.
 | 
			
		||||
type RoundTripperFunc func(req *http.Request) (*http.Response, error)
 | 
			
		||||
 | 
			
		||||
// RoundTrip implements the RoundTripper interface.
 | 
			
		||||
func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
 | 
			
		||||
	return rt(r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentRoundTripperInFlight is a middleware that wraps the provided
 | 
			
		||||
// http.RoundTripper. It sets the provided prometheus.Gauge to the number of
 | 
			
		||||
// requests currently handled by the wrapped http.RoundTripper.
 | 
			
		||||
//
 | 
			
		||||
// See the example for ExampleInstrumentRoundTripperDuration for example usage.
 | 
			
		||||
func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripper) RoundTripperFunc {
 | 
			
		||||
	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
 | 
			
		||||
		gauge.Inc()
 | 
			
		||||
		defer gauge.Dec()
 | 
			
		||||
		return next.RoundTrip(r)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentRoundTripperCounter is a middleware that wraps the provided
 | 
			
		||||
// http.RoundTripper to observe the request result with the provided CounterVec.
 | 
			
		||||
// The CounterVec must have zero, one, or two labels. The only allowed label
 | 
			
		||||
// names are "code" and "method". The function panics if any other instance
 | 
			
		||||
// labels are provided. Partitioning of the CounterVec happens by HTTP status
 | 
			
		||||
// code and/or HTTP method if the respective instance label names are present
 | 
			
		||||
// in the CounterVec. For unpartitioned counting, use a CounterVec with
 | 
			
		||||
// zero labels.
 | 
			
		||||
//
 | 
			
		||||
// If the wrapped RoundTripper panics or returns a non-nil error, the Counter
 | 
			
		||||
// is not incremented.
 | 
			
		||||
//
 | 
			
		||||
// See the example for ExampleInstrumentRoundTripperDuration for example usage.
 | 
			
		||||
func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper) RoundTripperFunc {
 | 
			
		||||
	code, method := checkLabels(counter)
 | 
			
		||||
 | 
			
		||||
	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
 | 
			
		||||
		resp, err := next.RoundTrip(r)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			counter.With(labels(code, method, r.Method, resp.StatusCode)).Inc()
 | 
			
		||||
		}
 | 
			
		||||
		return resp, err
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentRoundTripperDuration is a middleware that wraps the provided
 | 
			
		||||
// http.RoundTripper to observe the request duration with the provided ObserverVec.
 | 
			
		||||
// The ObserverVec must have zero, one, or two labels. The only allowed label
 | 
			
		||||
// names are "code" and "method". The function panics if any other instance
 | 
			
		||||
// labels are provided. The Observe method of the Observer in the ObserverVec
 | 
			
		||||
// is called with the request duration in seconds. Partitioning happens by HTTP
 | 
			
		||||
// status code and/or HTTP method if the respective instance label names are
 | 
			
		||||
// present in the ObserverVec. For unpartitioned observations, use an
 | 
			
		||||
// ObserverVec with zero labels. Note that partitioning of Histograms is
 | 
			
		||||
// expensive and should be used judiciously.
 | 
			
		||||
//
 | 
			
		||||
// If the wrapped RoundTripper panics or returns a non-nil error, no values are
 | 
			
		||||
// reported.
 | 
			
		||||
func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper) RoundTripperFunc {
 | 
			
		||||
	code, method := checkLabels(obs)
 | 
			
		||||
 | 
			
		||||
	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
 | 
			
		||||
		start := time.Now()
 | 
			
		||||
		resp, err := next.RoundTrip(r)
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			obs.With(labels(code, method, r.Method, resp.StatusCode)).Observe(time.Since(start).Seconds())
 | 
			
		||||
		}
 | 
			
		||||
		return resp, err
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										142
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client_1_8.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,142 @@
 | 
			
		||||
// Copyright 2017 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// +build go1.8
 | 
			
		||||
 | 
			
		||||
package promhttp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/http/httptrace"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// InstrumentTrace is used to offer flexibility in instrumenting the available
 | 
			
		||||
// httptrace.ClientTrace hook functions. Each function is passed a float64
 | 
			
		||||
// representing the time in seconds since the start of the http request. A user
 | 
			
		||||
// may choose to use separately buckets Histograms, or implement custom
 | 
			
		||||
// instance labels on a per function basis.
 | 
			
		||||
type InstrumentTrace struct {
 | 
			
		||||
	GotConn              func(float64)
 | 
			
		||||
	PutIdleConn          func(float64)
 | 
			
		||||
	GotFirstResponseByte func(float64)
 | 
			
		||||
	Got100Continue       func(float64)
 | 
			
		||||
	DNSStart             func(float64)
 | 
			
		||||
	DNSDone              func(float64)
 | 
			
		||||
	ConnectStart         func(float64)
 | 
			
		||||
	ConnectDone          func(float64)
 | 
			
		||||
	TLSHandshakeStart    func(float64)
 | 
			
		||||
	TLSHandshakeDone     func(float64)
 | 
			
		||||
	WroteHeaders         func(float64)
 | 
			
		||||
	Wait100Continue      func(float64)
 | 
			
		||||
	WroteRequest         func(float64)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentRoundTripperTrace is a middleware that wraps the provided
 | 
			
		||||
// RoundTripper and reports times to hook functions provided in the
 | 
			
		||||
// InstrumentTrace struct. Hook functions that are not present in the provided
 | 
			
		||||
// InstrumentTrace struct are ignored. Times reported to the hook functions are
 | 
			
		||||
// time since the start of the request. Note that partitioning of Histograms
 | 
			
		||||
// is expensive and should be used judiciously.
 | 
			
		||||
//
 | 
			
		||||
// For hook functions that receive an error as an argument, no observations are
 | 
			
		||||
// made in the event of a non-nil error value.
 | 
			
		||||
//
 | 
			
		||||
// See the example for ExampleInstrumentRoundTripperDuration for example usage.
 | 
			
		||||
func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc {
 | 
			
		||||
	return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
 | 
			
		||||
		start := time.Now()
 | 
			
		||||
 | 
			
		||||
		trace := &httptrace.ClientTrace{
 | 
			
		||||
			GotConn: func(_ httptrace.GotConnInfo) {
 | 
			
		||||
				if it.GotConn != nil {
 | 
			
		||||
					it.GotConn(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			PutIdleConn: func(err error) {
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				if it.PutIdleConn != nil {
 | 
			
		||||
					it.PutIdleConn(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			DNSStart: func(_ httptrace.DNSStartInfo) {
 | 
			
		||||
				if it.DNSStart != nil {
 | 
			
		||||
					it.DNSStart(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			DNSDone: func(_ httptrace.DNSDoneInfo) {
 | 
			
		||||
				if it.DNSStart != nil {
 | 
			
		||||
					it.DNSStart(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			ConnectStart: func(_, _ string) {
 | 
			
		||||
				if it.ConnectStart != nil {
 | 
			
		||||
					it.ConnectStart(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			ConnectDone: func(_, _ string, err error) {
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				if it.ConnectDone != nil {
 | 
			
		||||
					it.ConnectDone(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			GotFirstResponseByte: func() {
 | 
			
		||||
				if it.GotFirstResponseByte != nil {
 | 
			
		||||
					it.GotFirstResponseByte(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			Got100Continue: func() {
 | 
			
		||||
				if it.Got100Continue != nil {
 | 
			
		||||
					it.Got100Continue(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			TLSHandshakeStart: func() {
 | 
			
		||||
				if it.TLSHandshakeStart != nil {
 | 
			
		||||
					it.TLSHandshakeStart(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			TLSHandshakeDone: func(_ tls.ConnectionState, err error) {
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				if it.TLSHandshakeDone != nil {
 | 
			
		||||
					it.TLSHandshakeDone(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			WroteHeaders: func() {
 | 
			
		||||
				if it.WroteHeaders != nil {
 | 
			
		||||
					it.WroteHeaders(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			Wait100Continue: func() {
 | 
			
		||||
				if it.Wait100Continue != nil {
 | 
			
		||||
					it.Wait100Continue(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			WroteRequest: func(_ httptrace.WroteRequestInfo) {
 | 
			
		||||
				if it.WroteRequest != nil {
 | 
			
		||||
					it.WroteRequest(time.Since(start).Seconds())
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
		r = r.WithContext(httptrace.WithClientTrace(context.Background(), trace))
 | 
			
		||||
 | 
			
		||||
		return next.RoundTrip(r)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										505
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										505
									
								
								vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,505 @@
 | 
			
		||||
// Copyright 2017 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package promhttp
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	dto "github.com/prometheus/client_model/go"
 | 
			
		||||
 | 
			
		||||
	"github.com/prometheus/client_golang/prometheus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// magicString is used for the hacky label test in checkLabels. Remove once fixed.
 | 
			
		||||
const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa"
 | 
			
		||||
 | 
			
		||||
// InstrumentHandlerInFlight is a middleware that wraps the provided
 | 
			
		||||
// http.Handler. It sets the provided prometheus.Gauge to the number of
 | 
			
		||||
// requests currently handled by the wrapped http.Handler.
 | 
			
		||||
//
 | 
			
		||||
// See the example for InstrumentHandlerDuration for example usage.
 | 
			
		||||
func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handler {
 | 
			
		||||
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		g.Inc()
 | 
			
		||||
		defer g.Dec()
 | 
			
		||||
		next.ServeHTTP(w, r)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentHandlerDuration is a middleware that wraps the provided
 | 
			
		||||
// http.Handler to observe the request duration with the provided ObserverVec.
 | 
			
		||||
// The ObserverVec must have zero, one, or two labels. The only allowed label
 | 
			
		||||
// names are "code" and "method". The function panics if any other instance
 | 
			
		||||
// labels are provided. The Observe method of the Observer in the ObserverVec
 | 
			
		||||
// is called with the request duration in seconds. Partitioning happens by HTTP
 | 
			
		||||
// status code and/or HTTP method if the respective instance label names are
 | 
			
		||||
// present in the ObserverVec. For unpartitioned observations, use an
 | 
			
		||||
// ObserverVec with zero labels. Note that partitioning of Histograms is
 | 
			
		||||
// expensive and should be used judiciously.
 | 
			
		||||
//
 | 
			
		||||
// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
 | 
			
		||||
//
 | 
			
		||||
// If the wrapped Handler panics, no values are reported.
 | 
			
		||||
func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
 | 
			
		||||
	code, method := checkLabels(obs)
 | 
			
		||||
 | 
			
		||||
	if code {
 | 
			
		||||
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
			now := time.Now()
 | 
			
		||||
			d := newDelegator(w, nil)
 | 
			
		||||
			next.ServeHTTP(d, r)
 | 
			
		||||
 | 
			
		||||
			obs.With(labels(code, method, r.Method, d.Status())).Observe(time.Since(now).Seconds())
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		now := time.Now()
 | 
			
		||||
		next.ServeHTTP(w, r)
 | 
			
		||||
		obs.With(labels(code, method, r.Method, 0)).Observe(time.Since(now).Seconds())
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentHandlerCounter is a middleware that wraps the provided
 | 
			
		||||
// http.Handler to observe the request result with the provided CounterVec.
 | 
			
		||||
// The CounterVec must have zero, one, or two labels. The only allowed label
 | 
			
		||||
// names are "code" and "method". The function panics if any other instance
 | 
			
		||||
// labels are provided. Partitioning of the CounterVec happens by HTTP status
 | 
			
		||||
// code and/or HTTP method if the respective instance label names are present
 | 
			
		||||
// in the CounterVec. For unpartitioned counting, use a CounterVec with
 | 
			
		||||
// zero labels.
 | 
			
		||||
//
 | 
			
		||||
// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
 | 
			
		||||
//
 | 
			
		||||
// If the wrapped Handler panics, the Counter is not incremented.
 | 
			
		||||
//
 | 
			
		||||
// See the example for InstrumentHandlerDuration for example usage.
 | 
			
		||||
func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler) http.HandlerFunc {
 | 
			
		||||
	code, method := checkLabels(counter)
 | 
			
		||||
 | 
			
		||||
	if code {
 | 
			
		||||
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
			d := newDelegator(w, nil)
 | 
			
		||||
			next.ServeHTTP(d, r)
 | 
			
		||||
			counter.With(labels(code, method, r.Method, d.Status())).Inc()
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		next.ServeHTTP(w, r)
 | 
			
		||||
		counter.With(labels(code, method, r.Method, 0)).Inc()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided
 | 
			
		||||
// http.Handler to observe with the provided ObserverVec the request duration
 | 
			
		||||
// until the response headers are written. The ObserverVec must have zero, one,
 | 
			
		||||
// or two labels. The only allowed label names are "code" and "method". The
 | 
			
		||||
// function panics if any other instance labels are provided. The Observe
 | 
			
		||||
// method of the Observer in the ObserverVec is called with the request
 | 
			
		||||
// duration in seconds. Partitioning happens by HTTP status code and/or HTTP
 | 
			
		||||
// method if the respective instance label names are present in the
 | 
			
		||||
// ObserverVec. For unpartitioned observations, use an ObserverVec with zero
 | 
			
		||||
// labels. Note that partitioning of Histograms is expensive and should be used
 | 
			
		||||
// judiciously.
 | 
			
		||||
//
 | 
			
		||||
// If the wrapped Handler panics before calling WriteHeader, no value is
 | 
			
		||||
// reported.
 | 
			
		||||
//
 | 
			
		||||
// See the example for InstrumentHandlerDuration for example usage.
 | 
			
		||||
func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
 | 
			
		||||
	code, method := checkLabels(obs)
 | 
			
		||||
 | 
			
		||||
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		now := time.Now()
 | 
			
		||||
		d := newDelegator(w, func(status int) {
 | 
			
		||||
			obs.With(labels(code, method, r.Method, status)).Observe(time.Since(now).Seconds())
 | 
			
		||||
		})
 | 
			
		||||
		next.ServeHTTP(d, r)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentHandlerRequestSize is a middleware that wraps the provided
 | 
			
		||||
// http.Handler to observe the request size with the provided ObserverVec.
 | 
			
		||||
// The ObserverVec must have zero, one, or two labels. The only allowed label
 | 
			
		||||
// names are "code" and "method". The function panics if any other instance
 | 
			
		||||
// labels are provided. The Observe method of the Observer in the ObserverVec
 | 
			
		||||
// is called with the request size in bytes. Partitioning happens by HTTP
 | 
			
		||||
// status code and/or HTTP method if the respective instance label names are
 | 
			
		||||
// present in the ObserverVec. For unpartitioned observations, use an
 | 
			
		||||
// ObserverVec with zero labels. Note that partitioning of Histograms is
 | 
			
		||||
// expensive and should be used judiciously.
 | 
			
		||||
//
 | 
			
		||||
// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
 | 
			
		||||
//
 | 
			
		||||
// If the wrapped Handler panics, no values are reported.
 | 
			
		||||
//
 | 
			
		||||
// See the example for InstrumentHandlerDuration for example usage.
 | 
			
		||||
func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
 | 
			
		||||
	code, method := checkLabels(obs)
 | 
			
		||||
 | 
			
		||||
	if code {
 | 
			
		||||
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
			d := newDelegator(w, nil)
 | 
			
		||||
			next.ServeHTTP(d, r)
 | 
			
		||||
			size := computeApproximateRequestSize(r)
 | 
			
		||||
			obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(size))
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		next.ServeHTTP(w, r)
 | 
			
		||||
		size := computeApproximateRequestSize(r)
 | 
			
		||||
		obs.With(labels(code, method, r.Method, 0)).Observe(float64(size))
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InstrumentHandlerResponseSize is a middleware that wraps the provided
 | 
			
		||||
// http.Handler to observe the response size with the provided ObserverVec.
 | 
			
		||||
// The ObserverVec must have zero, one, or two labels. The only allowed label
 | 
			
		||||
// names are "code" and "method". The function panics if any other instance
 | 
			
		||||
// labels are provided. The Observe method of the Observer in the ObserverVec
 | 
			
		||||
// is called with the response size in bytes. Partitioning happens by HTTP
 | 
			
		||||
// status code and/or HTTP method if the respective instance label names are
 | 
			
		||||
// present in the ObserverVec. For unpartitioned observations, use an
 | 
			
		||||
// ObserverVec with zero labels. Note that partitioning of Histograms is
 | 
			
		||||
// expensive and should be used judiciously.
 | 
			
		||||
//
 | 
			
		||||
// If the wrapped Handler does not set a status code, a status code of 200 is assumed.
 | 
			
		||||
//
 | 
			
		||||
// If the wrapped Handler panics, no values are reported.
 | 
			
		||||
//
 | 
			
		||||
// See the example for InstrumentHandlerDuration for example usage.
 | 
			
		||||
func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler) http.Handler {
 | 
			
		||||
	code, method := checkLabels(obs)
 | 
			
		||||
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		d := newDelegator(w, nil)
 | 
			
		||||
		next.ServeHTTP(d, r)
 | 
			
		||||
		obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(d.Written()))
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func checkLabels(c prometheus.Collector) (code bool, method bool) {
 | 
			
		||||
	// TODO(beorn7): Remove this hacky way to check for instance labels
 | 
			
		||||
	// once Descriptors can have their dimensionality queried.
 | 
			
		||||
	var (
 | 
			
		||||
		desc *prometheus.Desc
 | 
			
		||||
		pm   dto.Metric
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	descc := make(chan *prometheus.Desc, 1)
 | 
			
		||||
	c.Describe(descc)
 | 
			
		||||
 | 
			
		||||
	select {
 | 
			
		||||
	case desc = <-descc:
 | 
			
		||||
	default:
 | 
			
		||||
		panic("no description provided by collector")
 | 
			
		||||
	}
 | 
			
		||||
	select {
 | 
			
		||||
	case <-descc:
 | 
			
		||||
		panic("more than one description provided by collector")
 | 
			
		||||
	default:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	close(descc)
 | 
			
		||||
 | 
			
		||||
	if _, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0); err == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if m, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, magicString); err == nil {
 | 
			
		||||
		if err := m.Write(&pm); err != nil {
 | 
			
		||||
			panic("error checking metric for labels")
 | 
			
		||||
		}
 | 
			
		||||
		for _, label := range pm.Label {
 | 
			
		||||
			name, value := label.GetName(), label.GetValue()
 | 
			
		||||
			if value != magicString {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			switch name {
 | 
			
		||||
			case "code":
 | 
			
		||||
				code = true
 | 
			
		||||
			case "method":
 | 
			
		||||
				method = true
 | 
			
		||||
			default:
 | 
			
		||||
				panic("metric partitioned with non-supported labels")
 | 
			
		||||
			}
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		panic("previously set label not found – this must never happen")
 | 
			
		||||
	}
 | 
			
		||||
	if m, err := prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, magicString, magicString); err == nil {
 | 
			
		||||
		if err := m.Write(&pm); err != nil {
 | 
			
		||||
			panic("error checking metric for labels")
 | 
			
		||||
		}
 | 
			
		||||
		for _, label := range pm.Label {
 | 
			
		||||
			name, value := label.GetName(), label.GetValue()
 | 
			
		||||
			if value != magicString {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if name == "code" || name == "method" {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			panic("metric partitioned with non-supported labels")
 | 
			
		||||
		}
 | 
			
		||||
		code = true
 | 
			
		||||
		method = true
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	panic("metric partitioned with non-supported labels")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// emptyLabels is a one-time allocation for non-partitioned metrics to avoid
 | 
			
		||||
// unnecessary allocations on each request.
 | 
			
		||||
var emptyLabels = prometheus.Labels{}
 | 
			
		||||
 | 
			
		||||
func labels(code, method bool, reqMethod string, status int) prometheus.Labels {
 | 
			
		||||
	if !(code || method) {
 | 
			
		||||
		return emptyLabels
 | 
			
		||||
	}
 | 
			
		||||
	labels := prometheus.Labels{}
 | 
			
		||||
 | 
			
		||||
	if code {
 | 
			
		||||
		labels["code"] = sanitizeCode(status)
 | 
			
		||||
	}
 | 
			
		||||
	if method {
 | 
			
		||||
		labels["method"] = sanitizeMethod(reqMethod)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return labels
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func computeApproximateRequestSize(r *http.Request) int {
 | 
			
		||||
	s := 0
 | 
			
		||||
	if r.URL != nil {
 | 
			
		||||
		s += len(r.URL.String())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s += len(r.Method)
 | 
			
		||||
	s += len(r.Proto)
 | 
			
		||||
	for name, values := range r.Header {
 | 
			
		||||
		s += len(name)
 | 
			
		||||
		for _, value := range values {
 | 
			
		||||
			s += len(value)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	s += len(r.Host)
 | 
			
		||||
 | 
			
		||||
	// N.B. r.Form and r.MultipartForm are assumed to be included in r.URL.
 | 
			
		||||
 | 
			
		||||
	if r.ContentLength != -1 {
 | 
			
		||||
		s += int(r.ContentLength)
 | 
			
		||||
	}
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func sanitizeMethod(m string) string {
 | 
			
		||||
	switch m {
 | 
			
		||||
	case "GET", "get":
 | 
			
		||||
		return "get"
 | 
			
		||||
	case "PUT", "put":
 | 
			
		||||
		return "put"
 | 
			
		||||
	case "HEAD", "head":
 | 
			
		||||
		return "head"
 | 
			
		||||
	case "POST", "post":
 | 
			
		||||
		return "post"
 | 
			
		||||
	case "DELETE", "delete":
 | 
			
		||||
		return "delete"
 | 
			
		||||
	case "CONNECT", "connect":
 | 
			
		||||
		return "connect"
 | 
			
		||||
	case "OPTIONS", "options":
 | 
			
		||||
		return "options"
 | 
			
		||||
	case "NOTIFY", "notify":
 | 
			
		||||
		return "notify"
 | 
			
		||||
	default:
 | 
			
		||||
		return strings.ToLower(m)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// If the wrapped http.Handler has not set a status code, i.e. the value is
 | 
			
		||||
// currently 0, santizeCode will return 200, for consistency with behavior in
 | 
			
		||||
// the stdlib.
 | 
			
		||||
func sanitizeCode(s int) string {
 | 
			
		||||
	switch s {
 | 
			
		||||
	case 100:
 | 
			
		||||
		return "100"
 | 
			
		||||
	case 101:
 | 
			
		||||
		return "101"
 | 
			
		||||
 | 
			
		||||
	case 200, 0:
 | 
			
		||||
		return "200"
 | 
			
		||||
	case 201:
 | 
			
		||||
		return "201"
 | 
			
		||||
	case 202:
 | 
			
		||||
		return "202"
 | 
			
		||||
	case 203:
 | 
			
		||||
		return "203"
 | 
			
		||||
	case 204:
 | 
			
		||||
		return "204"
 | 
			
		||||
	case 205:
 | 
			
		||||
		return "205"
 | 
			
		||||
	case 206:
 | 
			
		||||
		return "206"
 | 
			
		||||
 | 
			
		||||
	case 300:
 | 
			
		||||
		return "300"
 | 
			
		||||
	case 301:
 | 
			
		||||
		return "301"
 | 
			
		||||
	case 302:
 | 
			
		||||
		return "302"
 | 
			
		||||
	case 304:
 | 
			
		||||
		return "304"
 | 
			
		||||
	case 305:
 | 
			
		||||
		return "305"
 | 
			
		||||
	case 307:
 | 
			
		||||
		return "307"
 | 
			
		||||
 | 
			
		||||
	case 400:
 | 
			
		||||
		return "400"
 | 
			
		||||
	case 401:
 | 
			
		||||
		return "401"
 | 
			
		||||
	case 402:
 | 
			
		||||
		return "402"
 | 
			
		||||
	case 403:
 | 
			
		||||
		return "403"
 | 
			
		||||
	case 404:
 | 
			
		||||
		return "404"
 | 
			
		||||
	case 405:
 | 
			
		||||
		return "405"
 | 
			
		||||
	case 406:
 | 
			
		||||
		return "406"
 | 
			
		||||
	case 407:
 | 
			
		||||
		return "407"
 | 
			
		||||
	case 408:
 | 
			
		||||
		return "408"
 | 
			
		||||
	case 409:
 | 
			
		||||
		return "409"
 | 
			
		||||
	case 410:
 | 
			
		||||
		return "410"
 | 
			
		||||
	case 411:
 | 
			
		||||
		return "411"
 | 
			
		||||
	case 412:
 | 
			
		||||
		return "412"
 | 
			
		||||
	case 413:
 | 
			
		||||
		return "413"
 | 
			
		||||
	case 414:
 | 
			
		||||
		return "414"
 | 
			
		||||
	case 415:
 | 
			
		||||
		return "415"
 | 
			
		||||
	case 416:
 | 
			
		||||
		return "416"
 | 
			
		||||
	case 417:
 | 
			
		||||
		return "417"
 | 
			
		||||
	case 418:
 | 
			
		||||
		return "418"
 | 
			
		||||
 | 
			
		||||
	case 500:
 | 
			
		||||
		return "500"
 | 
			
		||||
	case 501:
 | 
			
		||||
		return "501"
 | 
			
		||||
	case 502:
 | 
			
		||||
		return "502"
 | 
			
		||||
	case 503:
 | 
			
		||||
		return "503"
 | 
			
		||||
	case 504:
 | 
			
		||||
		return "504"
 | 
			
		||||
	case 505:
 | 
			
		||||
		return "505"
 | 
			
		||||
 | 
			
		||||
	case 428:
 | 
			
		||||
		return "428"
 | 
			
		||||
	case 429:
 | 
			
		||||
		return "429"
 | 
			
		||||
	case 431:
 | 
			
		||||
		return "431"
 | 
			
		||||
	case 511:
 | 
			
		||||
		return "511"
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		return strconv.Itoa(s)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type delegator interface {
 | 
			
		||||
	Status() int
 | 
			
		||||
	Written() int64
 | 
			
		||||
 | 
			
		||||
	http.ResponseWriter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type responseWriterDelegator struct {
 | 
			
		||||
	http.ResponseWriter
 | 
			
		||||
 | 
			
		||||
	handler, method    string
 | 
			
		||||
	status             int
 | 
			
		||||
	written            int64
 | 
			
		||||
	wroteHeader        bool
 | 
			
		||||
	observeWriteHeader func(int)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *responseWriterDelegator) Status() int {
 | 
			
		||||
	return r.status
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *responseWriterDelegator) Written() int64 {
 | 
			
		||||
	return r.written
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *responseWriterDelegator) WriteHeader(code int) {
 | 
			
		||||
	r.status = code
 | 
			
		||||
	r.wroteHeader = true
 | 
			
		||||
	r.ResponseWriter.WriteHeader(code)
 | 
			
		||||
	if r.observeWriteHeader != nil {
 | 
			
		||||
		r.observeWriteHeader(code)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *responseWriterDelegator) Write(b []byte) (int, error) {
 | 
			
		||||
	if !r.wroteHeader {
 | 
			
		||||
		r.WriteHeader(http.StatusOK)
 | 
			
		||||
	}
 | 
			
		||||
	n, err := r.ResponseWriter.Write(b)
 | 
			
		||||
	r.written += int64(n)
 | 
			
		||||
	return n, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type fancyDelegator struct {
 | 
			
		||||
	*responseWriterDelegator
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *fancyDelegator) CloseNotify() <-chan bool {
 | 
			
		||||
	return r.ResponseWriter.(http.CloseNotifier).CloseNotify()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *fancyDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
 | 
			
		||||
	return r.ResponseWriter.(http.Hijacker).Hijack()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *fancyDelegator) Flush() {
 | 
			
		||||
	r.ResponseWriter.(http.Flusher).Flush()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *fancyDelegator) ReadFrom(re io.Reader) (int64, error) {
 | 
			
		||||
	if !r.wroteHeader {
 | 
			
		||||
		r.WriteHeader(http.StatusOK)
 | 
			
		||||
	}
 | 
			
		||||
	n, err := r.ResponseWriter.(io.ReaderFrom).ReadFrom(re)
 | 
			
		||||
	r.written += n
 | 
			
		||||
	return n, err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										65
									
								
								vendor/github.com/prometheus/client_golang/prometheus/push.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										65
									
								
								vendor/github.com/prometheus/client_golang/prometheus/push.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,65 +0,0 @@
 | 
			
		||||
// Copyright 2015 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// Copyright (c) 2013, The Prometheus Authors
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Use of this source code is governed by a BSD-style license that can be found
 | 
			
		||||
// in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package prometheus
 | 
			
		||||
 | 
			
		||||
// Push triggers a metric collection by the default registry and pushes all
 | 
			
		||||
// collected metrics to the Pushgateway specified by addr. See the Pushgateway
 | 
			
		||||
// documentation for detailed implications of the job and instance
 | 
			
		||||
// parameter. instance can be left empty. You can use just host:port or ip:port
 | 
			
		||||
// as url, in which case 'http://' is added automatically. You can also include
 | 
			
		||||
// the schema in the URL. However, do not include the '/metrics/jobs/...' part.
 | 
			
		||||
//
 | 
			
		||||
// Note that all previously pushed metrics with the same job and instance will
 | 
			
		||||
// be replaced with the metrics pushed by this call. (It uses HTTP method 'PUT'
 | 
			
		||||
// to push to the Pushgateway.)
 | 
			
		||||
func Push(job, instance, url string) error {
 | 
			
		||||
	return defRegistry.Push(job, instance, url, "PUT")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PushAdd works like Push, but only previously pushed metrics with the same
 | 
			
		||||
// name (and the same job and instance) will be replaced. (It uses HTTP method
 | 
			
		||||
// 'POST' to push to the Pushgateway.)
 | 
			
		||||
func PushAdd(job, instance, url string) error {
 | 
			
		||||
	return defRegistry.Push(job, instance, url, "POST")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PushCollectors works like Push, but it does not collect from the default
 | 
			
		||||
// registry. Instead, it collects from the provided collectors. It is a
 | 
			
		||||
// convenient way to push only a few metrics.
 | 
			
		||||
func PushCollectors(job, instance, url string, collectors ...Collector) error {
 | 
			
		||||
	return pushCollectors(job, instance, url, "PUT", collectors...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PushAddCollectors works like PushAdd, but it does not collect from the
 | 
			
		||||
// default registry. Instead, it collects from the provided collectors. It is a
 | 
			
		||||
// convenient way to push only a few metrics.
 | 
			
		||||
func PushAddCollectors(job, instance, url string, collectors ...Collector) error {
 | 
			
		||||
	return pushCollectors(job, instance, url, "POST", collectors...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func pushCollectors(job, instance, url, method string, collectors ...Collector) error {
 | 
			
		||||
	r := newRegistry()
 | 
			
		||||
	for _, collector := range collectors {
 | 
			
		||||
		if _, err := r.Register(collector); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return r.Push(job, instance, url, method)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										945
									
								
								vendor/github.com/prometheus/client_golang/prometheus/registry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										945
									
								
								vendor/github.com/prometheus/client_golang/prometheus/registry.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										73
									
								
								vendor/github.com/prometheus/client_golang/prometheus/summary.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										73
									
								
								vendor/github.com/prometheus/client_golang/prometheus/summary.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -15,7 +15,6 @@ package prometheus
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"hash/fnv"
 | 
			
		||||
	"math"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"sync"
 | 
			
		||||
@@ -54,8 +53,11 @@ type Summary interface {
 | 
			
		||||
	Observe(float64)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DefObjectives are the default Summary quantile values.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: DefObjectives will not be used as the default objectives in
 | 
			
		||||
// v0.10 of the library. The default Summary will have no quantiles then.
 | 
			
		||||
var (
 | 
			
		||||
	// DefObjectives are the default Summary quantile values.
 | 
			
		||||
	DefObjectives = map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}
 | 
			
		||||
 | 
			
		||||
	errQuantileLabelNotAllowed = fmt.Errorf(
 | 
			
		||||
@@ -114,9 +116,15 @@ type SummaryOpts struct {
 | 
			
		||||
	ConstLabels Labels
 | 
			
		||||
 | 
			
		||||
	// Objectives defines the quantile rank estimates with their respective
 | 
			
		||||
	// absolute error. If Objectives[q] = e, then the value reported
 | 
			
		||||
	// for q will be the φ-quantile value for some φ between q-e and q+e.
 | 
			
		||||
	// The default value is DefObjectives.
 | 
			
		||||
	// absolute error. If Objectives[q] = e, then the value reported for q
 | 
			
		||||
	// will be the φ-quantile value for some φ between q-e and q+e.  The
 | 
			
		||||
	// default value is DefObjectives. It is used if Objectives is left at
 | 
			
		||||
	// its zero value (i.e. nil). To create a Summary without Objectives,
 | 
			
		||||
	// set it to an empty map (i.e. map[float64]float64{}).
 | 
			
		||||
	//
 | 
			
		||||
	// Deprecated: Note that the current value of DefObjectives is
 | 
			
		||||
	// deprecated. It will be replaced by an empty map in v0.10 of the
 | 
			
		||||
	// library. Please explicitly set Objectives to the desired value.
 | 
			
		||||
	Objectives map[float64]float64
 | 
			
		||||
 | 
			
		||||
	// MaxAge defines the duration for which an observation stays relevant
 | 
			
		||||
@@ -140,11 +148,11 @@ type SummaryOpts struct {
 | 
			
		||||
	BufCap uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: Great fuck-up with the sliding-window decay algorithm... The Merge
 | 
			
		||||
// method of perk/quantile is actually not working as advertised - and it might
 | 
			
		||||
// be unfixable, as the underlying algorithm is apparently not capable of
 | 
			
		||||
// merging summaries in the first place. To avoid using Merge, we are currently
 | 
			
		||||
// adding observations to _each_ age bucket, i.e. the effort to add a sample is
 | 
			
		||||
// Great fuck-up with the sliding-window decay algorithm... The Merge method of
 | 
			
		||||
// perk/quantile is actually not working as advertised - and it might be
 | 
			
		||||
// unfixable, as the underlying algorithm is apparently not capable of merging
 | 
			
		||||
// summaries in the first place. To avoid using Merge, we are currently adding
 | 
			
		||||
// observations to _each_ age bucket, i.e. the effort to add a sample is
 | 
			
		||||
// essentially multiplied by the number of age buckets. When rotating age
 | 
			
		||||
// buckets, we empty the previous head stream. On scrape time, we simply take
 | 
			
		||||
// the quantiles from the head stream (no merging required). Result: More effort
 | 
			
		||||
@@ -184,7 +192,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(opts.Objectives) == 0 {
 | 
			
		||||
	if opts.Objectives == nil {
 | 
			
		||||
		opts.Objectives = DefObjectives
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -228,12 +236,12 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
 | 
			
		||||
	}
 | 
			
		||||
	sort.Float64s(s.sortedObjectives)
 | 
			
		||||
 | 
			
		||||
	s.Init(s) // Init self-collection.
 | 
			
		||||
	s.init(s) // Init self-collection.
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type summary struct {
 | 
			
		||||
	SelfCollector
 | 
			
		||||
	selfCollector
 | 
			
		||||
 | 
			
		||||
	bufMtx sync.Mutex // Protects hotBuf and hotBufExpTime.
 | 
			
		||||
	mtx    sync.Mutex // Protects every other moving part.
 | 
			
		||||
@@ -391,7 +399,7 @@ func (s quantSort) Less(i, j int) bool {
 | 
			
		||||
// (e.g. HTTP request latencies, partitioned by status code and method). Create
 | 
			
		||||
// instances with NewSummaryVec.
 | 
			
		||||
type SummaryVec struct {
 | 
			
		||||
	MetricVec
 | 
			
		||||
	*MetricVec
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and
 | 
			
		||||
@@ -405,35 +413,30 @@ func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec {
 | 
			
		||||
		opts.ConstLabels,
 | 
			
		||||
	)
 | 
			
		||||
	return &SummaryVec{
 | 
			
		||||
		MetricVec: MetricVec{
 | 
			
		||||
			children: map[uint64]Metric{},
 | 
			
		||||
			desc:     desc,
 | 
			
		||||
			hash:     fnv.New64a(),
 | 
			
		||||
			newMetric: func(lvs ...string) Metric {
 | 
			
		||||
				return newSummary(desc, opts, lvs...)
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
 | 
			
		||||
			return newSummary(desc, opts, lvs...)
 | 
			
		||||
		}),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetMetricWithLabelValues replaces the method of the same name in
 | 
			
		||||
// MetricVec. The difference is that this method returns a Summary and not a
 | 
			
		||||
// Metric so that no type conversion is required.
 | 
			
		||||
func (m *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Summary, error) {
 | 
			
		||||
// GetMetricWithLabelValues replaces the method of the same name in MetricVec.
 | 
			
		||||
// The difference is that this method returns an Observer and not a Metric so
 | 
			
		||||
// that no type conversion to an Observer is required.
 | 
			
		||||
func (m *SummaryVec) GetMetricWithLabelValues(lvs ...string) (Observer, error) {
 | 
			
		||||
	metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
 | 
			
		||||
	if metric != nil {
 | 
			
		||||
		return metric.(Summary), err
 | 
			
		||||
		return metric.(Observer), err
 | 
			
		||||
	}
 | 
			
		||||
	return nil, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetMetricWith replaces the method of the same name in MetricVec. The
 | 
			
		||||
// difference is that this method returns a Summary and not a Metric so that no
 | 
			
		||||
// type conversion is required.
 | 
			
		||||
func (m *SummaryVec) GetMetricWith(labels Labels) (Summary, error) {
 | 
			
		||||
// difference is that this method returns an Observer and not a Metric so that
 | 
			
		||||
// no type conversion to an Observer is required.
 | 
			
		||||
func (m *SummaryVec) GetMetricWith(labels Labels) (Observer, error) {
 | 
			
		||||
	metric, err := m.MetricVec.GetMetricWith(labels)
 | 
			
		||||
	if metric != nil {
 | 
			
		||||
		return metric.(Summary), err
 | 
			
		||||
		return metric.(Observer), err
 | 
			
		||||
	}
 | 
			
		||||
	return nil, err
 | 
			
		||||
}
 | 
			
		||||
@@ -442,15 +445,15 @@ func (m *SummaryVec) GetMetricWith(labels Labels) (Summary, error) {
 | 
			
		||||
// GetMetricWithLabelValues would have returned an error. By not returning an
 | 
			
		||||
// error, WithLabelValues allows shortcuts like
 | 
			
		||||
//     myVec.WithLabelValues("404", "GET").Observe(42.21)
 | 
			
		||||
func (m *SummaryVec) WithLabelValues(lvs ...string) Summary {
 | 
			
		||||
	return m.MetricVec.WithLabelValues(lvs...).(Summary)
 | 
			
		||||
func (m *SummaryVec) WithLabelValues(lvs ...string) Observer {
 | 
			
		||||
	return m.MetricVec.WithLabelValues(lvs...).(Observer)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// With works as GetMetricWith, but panics where GetMetricWithLabels would have
 | 
			
		||||
// returned an error. By not returning an error, With allows shortcuts like
 | 
			
		||||
//     myVec.With(Labels{"code": "404", "method": "GET"}).Observe(42.21)
 | 
			
		||||
func (m *SummaryVec) With(labels Labels) Summary {
 | 
			
		||||
	return m.MetricVec.With(labels).(Summary)
 | 
			
		||||
func (m *SummaryVec) With(labels Labels) Observer {
 | 
			
		||||
	return m.MetricVec.With(labels).(Observer)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type constSummary struct {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								vendor/github.com/prometheus/client_golang/prometheus/timer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								vendor/github.com/prometheus/client_golang/prometheus/timer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
// Copyright 2016 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package prometheus
 | 
			
		||||
 | 
			
		||||
import "time"
 | 
			
		||||
 | 
			
		||||
// Timer is a helper type to time functions. Use NewTimer to create new
 | 
			
		||||
// instances.
 | 
			
		||||
type Timer struct {
 | 
			
		||||
	begin    time.Time
 | 
			
		||||
	observer Observer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewTimer creates a new Timer. The provided Observer is used to observe a
 | 
			
		||||
// duration in seconds. Timer is usually used to time a function call in the
 | 
			
		||||
// following way:
 | 
			
		||||
//    func TimeMe() {
 | 
			
		||||
//        timer := NewTimer(myHistogram)
 | 
			
		||||
//        defer timer.ObserveDuration()
 | 
			
		||||
//        // Do actual work.
 | 
			
		||||
//    }
 | 
			
		||||
func NewTimer(o Observer) *Timer {
 | 
			
		||||
	return &Timer{
 | 
			
		||||
		begin:    time.Now(),
 | 
			
		||||
		observer: o,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ObserveDuration records the duration passed since the Timer was created with
 | 
			
		||||
// NewTimer. It calls the Observe method of the Observer provided during
 | 
			
		||||
// construction with the duration in seconds as an argument. ObserveDuration is
 | 
			
		||||
// usually called with a defer statement.
 | 
			
		||||
func (t *Timer) ObserveDuration() {
 | 
			
		||||
	if t.observer != nil {
 | 
			
		||||
		t.observer.Observe(time.Since(t.begin).Seconds())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/github.com/prometheus/client_golang/prometheus/untyped.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/prometheus/client_golang/prometheus/untyped.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -13,8 +13,6 @@
 | 
			
		||||
 | 
			
		||||
package prometheus
 | 
			
		||||
 | 
			
		||||
import "hash/fnv"
 | 
			
		||||
 | 
			
		||||
// Untyped is a Metric that represents a single numerical value that can
 | 
			
		||||
// arbitrarily go up and down.
 | 
			
		||||
//
 | 
			
		||||
@@ -22,6 +20,11 @@ import "hash/fnv"
 | 
			
		||||
// no type information is implied.
 | 
			
		||||
//
 | 
			
		||||
// To create Untyped instances, use NewUntyped.
 | 
			
		||||
//
 | 
			
		||||
// Deprecated: The Untyped type is deprecated because it doesn't make sense in
 | 
			
		||||
// direct instrumentation. If you need to mirror an external metric of unknown
 | 
			
		||||
// type (usually while writing exporters), Use MustNewConstMetric to create an
 | 
			
		||||
// untyped metric instance on the fly.
 | 
			
		||||
type Untyped interface {
 | 
			
		||||
	Metric
 | 
			
		||||
	Collector
 | 
			
		||||
@@ -58,7 +61,7 @@ func NewUntyped(opts UntypedOpts) Untyped {
 | 
			
		||||
// labels. This is used if you want to count the same thing partitioned by
 | 
			
		||||
// various dimensions. Create instances with NewUntypedVec.
 | 
			
		||||
type UntypedVec struct {
 | 
			
		||||
	MetricVec
 | 
			
		||||
	*MetricVec
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewUntypedVec creates a new UntypedVec based on the provided UntypedOpts and
 | 
			
		||||
@@ -72,14 +75,9 @@ func NewUntypedVec(opts UntypedOpts, labelNames []string) *UntypedVec {
 | 
			
		||||
		opts.ConstLabels,
 | 
			
		||||
	)
 | 
			
		||||
	return &UntypedVec{
 | 
			
		||||
		MetricVec: MetricVec{
 | 
			
		||||
			children: map[uint64]Metric{},
 | 
			
		||||
			desc:     desc,
 | 
			
		||||
			hash:     fnv.New64a(),
 | 
			
		||||
			newMetric: func(lvs ...string) Metric {
 | 
			
		||||
				return newValue(desc, UntypedValue, 0, lvs...)
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		MetricVec: newMetricVec(desc, func(lvs ...string) Metric {
 | 
			
		||||
			return newValue(desc, UntypedValue, 0, lvs...)
 | 
			
		||||
		}),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/github.com/prometheus/client_golang/prometheus/value.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								vendor/github.com/prometheus/client_golang/prometheus/value.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -19,6 +19,7 @@ import (
 | 
			
		||||
	"math"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"sync/atomic"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	dto "github.com/prometheus/client_model/go"
 | 
			
		||||
 | 
			
		||||
@@ -43,12 +44,12 @@ var errInconsistentCardinality = errors.New("inconsistent label cardinality")
 | 
			
		||||
// ValueType. This is a low-level building block used by the library to back the
 | 
			
		||||
// implementations of Counter, Gauge, and Untyped.
 | 
			
		||||
type value struct {
 | 
			
		||||
	// valBits containst the bits of the represented float64 value. It has
 | 
			
		||||
	// valBits contains the bits of the represented float64 value. It has
 | 
			
		||||
	// to go first in the struct to guarantee alignment for atomic
 | 
			
		||||
	// operations.  http://golang.org/pkg/sync/atomic/#pkg-note-BUG
 | 
			
		||||
	valBits uint64
 | 
			
		||||
 | 
			
		||||
	SelfCollector
 | 
			
		||||
	selfCollector
 | 
			
		||||
 | 
			
		||||
	desc       *Desc
 | 
			
		||||
	valType    ValueType
 | 
			
		||||
@@ -68,7 +69,7 @@ func newValue(desc *Desc, valueType ValueType, val float64, labelValues ...strin
 | 
			
		||||
		valBits:    math.Float64bits(val),
 | 
			
		||||
		labelPairs: makeLabelPairs(desc, labelValues),
 | 
			
		||||
	}
 | 
			
		||||
	result.Init(result)
 | 
			
		||||
	result.init(result)
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -80,6 +81,10 @@ func (v *value) Set(val float64) {
 | 
			
		||||
	atomic.StoreUint64(&v.valBits, math.Float64bits(val))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v *value) SetToCurrentTime() {
 | 
			
		||||
	v.Set(float64(time.Now().UnixNano()) / 1e9)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v *value) Inc() {
 | 
			
		||||
	v.Add(1)
 | 
			
		||||
}
 | 
			
		||||
@@ -113,7 +118,7 @@ func (v *value) Write(out *dto.Metric) error {
 | 
			
		||||
// library to back the implementations of CounterFunc, GaugeFunc, and
 | 
			
		||||
// UntypedFunc.
 | 
			
		||||
type valueFunc struct {
 | 
			
		||||
	SelfCollector
 | 
			
		||||
	selfCollector
 | 
			
		||||
 | 
			
		||||
	desc       *Desc
 | 
			
		||||
	valType    ValueType
 | 
			
		||||
@@ -134,7 +139,7 @@ func newValueFunc(desc *Desc, valueType ValueType, function func() float64) *val
 | 
			
		||||
		function:   function,
 | 
			
		||||
		labelPairs: makeLabelPairs(desc, nil),
 | 
			
		||||
	}
 | 
			
		||||
	result.Init(result)
 | 
			
		||||
	result.init(result)
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										253
									
								
								vendor/github.com/prometheus/client_golang/prometheus/vec.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										253
									
								
								vendor/github.com/prometheus/client_golang/prometheus/vec.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -14,10 +14,10 @@
 | 
			
		||||
package prometheus
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"hash"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"github.com/prometheus/common/model"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MetricVec is a Collector to bundle metrics of the same name that
 | 
			
		||||
@@ -26,17 +26,32 @@ import (
 | 
			
		||||
// type. GaugeVec, CounterVec, SummaryVec, and UntypedVec are examples already
 | 
			
		||||
// provided in this package.
 | 
			
		||||
type MetricVec struct {
 | 
			
		||||
	mtx      sync.RWMutex // Protects not only children, but also hash and buf.
 | 
			
		||||
	children map[uint64]Metric
 | 
			
		||||
	mtx      sync.RWMutex // Protects the children.
 | 
			
		||||
	children map[uint64][]metricWithLabelValues
 | 
			
		||||
	desc     *Desc
 | 
			
		||||
 | 
			
		||||
	// hash is our own hash instance to avoid repeated allocations.
 | 
			
		||||
	hash hash.Hash64
 | 
			
		||||
	// buf is used to copy string contents into it for hashing,
 | 
			
		||||
	// again to avoid allocations.
 | 
			
		||||
	buf bytes.Buffer
 | 
			
		||||
	newMetric   func(labelValues ...string) Metric
 | 
			
		||||
	hashAdd     func(h uint64, s string) uint64 // replace hash function for testing collision handling
 | 
			
		||||
	hashAddByte func(h uint64, b byte) uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	newMetric func(labelValues ...string) Metric
 | 
			
		||||
// newMetricVec returns an initialized MetricVec. The concrete value is
 | 
			
		||||
// returned for embedding into another struct.
 | 
			
		||||
func newMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec {
 | 
			
		||||
	return &MetricVec{
 | 
			
		||||
		children:    map[uint64][]metricWithLabelValues{},
 | 
			
		||||
		desc:        desc,
 | 
			
		||||
		newMetric:   newMetric,
 | 
			
		||||
		hashAdd:     hashAdd,
 | 
			
		||||
		hashAddByte: hashAddByte,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// metricWithLabelValues provides the metric and its label values for
 | 
			
		||||
// disambiguation on hash collision.
 | 
			
		||||
type metricWithLabelValues struct {
 | 
			
		||||
	values []string
 | 
			
		||||
	metric Metric
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Describe implements Collector. The length of the returned slice
 | 
			
		||||
@@ -50,8 +65,10 @@ func (m *MetricVec) Collect(ch chan<- Metric) {
 | 
			
		||||
	m.mtx.RLock()
 | 
			
		||||
	defer m.mtx.RUnlock()
 | 
			
		||||
 | 
			
		||||
	for _, metric := range m.children {
 | 
			
		||||
		ch <- metric
 | 
			
		||||
	for _, metrics := range m.children {
 | 
			
		||||
		for _, metric := range metrics {
 | 
			
		||||
			ch <- metric.metric
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -80,14 +97,12 @@ func (m *MetricVec) Collect(ch chan<- Metric) {
 | 
			
		||||
// with a performance overhead (for creating and processing the Labels map).
 | 
			
		||||
// See also the GaugeVec example.
 | 
			
		||||
func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {
 | 
			
		||||
	m.mtx.Lock()
 | 
			
		||||
	defer m.mtx.Unlock()
 | 
			
		||||
 | 
			
		||||
	h, err := m.hashLabelValues(lvs)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return m.getOrCreateMetric(h, lvs...), nil
 | 
			
		||||
 | 
			
		||||
	return m.getOrCreateMetricWithLabelValues(h, lvs), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetMetricWith returns the Metric for the given Labels map (the label names
 | 
			
		||||
@@ -103,18 +118,12 @@ func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {
 | 
			
		||||
// GetMetricWithLabelValues(...string). See there for pros and cons of the two
 | 
			
		||||
// methods.
 | 
			
		||||
func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {
 | 
			
		||||
	m.mtx.Lock()
 | 
			
		||||
	defer m.mtx.Unlock()
 | 
			
		||||
 | 
			
		||||
	h, err := m.hashLabels(labels)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	lvs := make([]string, len(labels))
 | 
			
		||||
	for i, label := range m.desc.variableLabels {
 | 
			
		||||
		lvs[i] = labels[label]
 | 
			
		||||
	}
 | 
			
		||||
	return m.getOrCreateMetric(h, lvs...), nil
 | 
			
		||||
 | 
			
		||||
	return m.getOrCreateMetricWithLabels(h, labels), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WithLabelValues works as GetMetricWithLabelValues, but panics if an error
 | 
			
		||||
@@ -162,11 +171,7 @@ func (m *MetricVec) DeleteLabelValues(lvs ...string) bool {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if _, has := m.children[h]; !has {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	delete(m.children, h)
 | 
			
		||||
	return true
 | 
			
		||||
	return m.deleteByHashWithLabelValues(h, lvs)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Delete deletes the metric where the variable labels are the same as those
 | 
			
		||||
@@ -187,10 +192,50 @@ func (m *MetricVec) Delete(labels Labels) bool {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if _, has := m.children[h]; !has {
 | 
			
		||||
 | 
			
		||||
	return m.deleteByHashWithLabels(h, labels)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// deleteByHashWithLabelValues removes the metric from the hash bucket h. If
 | 
			
		||||
// there are multiple matches in the bucket, use lvs to select a metric and
 | 
			
		||||
// remove only that metric.
 | 
			
		||||
func (m *MetricVec) deleteByHashWithLabelValues(h uint64, lvs []string) bool {
 | 
			
		||||
	metrics, ok := m.children[h]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	delete(m.children, h)
 | 
			
		||||
 | 
			
		||||
	i := m.findMetricWithLabelValues(metrics, lvs)
 | 
			
		||||
	if i >= len(metrics) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(metrics) > 1 {
 | 
			
		||||
		m.children[h] = append(metrics[:i], metrics[i+1:]...)
 | 
			
		||||
	} else {
 | 
			
		||||
		delete(m.children, h)
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// deleteByHashWithLabels removes the metric from the hash bucket h. If there
 | 
			
		||||
// are multiple matches in the bucket, use lvs to select a metric and remove
 | 
			
		||||
// only that metric.
 | 
			
		||||
func (m *MetricVec) deleteByHashWithLabels(h uint64, labels Labels) bool {
 | 
			
		||||
	metrics, ok := m.children[h]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	i := m.findMetricWithLabels(metrics, labels)
 | 
			
		||||
	if i >= len(metrics) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(metrics) > 1 {
 | 
			
		||||
		m.children[h] = append(metrics[:i], metrics[i+1:]...)
 | 
			
		||||
	} else {
 | 
			
		||||
		delete(m.children, h)
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -208,40 +253,152 @@ func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {
 | 
			
		||||
	if len(vals) != len(m.desc.variableLabels) {
 | 
			
		||||
		return 0, errInconsistentCardinality
 | 
			
		||||
	}
 | 
			
		||||
	m.hash.Reset()
 | 
			
		||||
	h := hashNew()
 | 
			
		||||
	for _, val := range vals {
 | 
			
		||||
		m.buf.Reset()
 | 
			
		||||
		m.buf.WriteString(val)
 | 
			
		||||
		m.hash.Write(m.buf.Bytes())
 | 
			
		||||
		h = m.hashAdd(h, val)
 | 
			
		||||
		h = m.hashAddByte(h, model.SeparatorByte)
 | 
			
		||||
	}
 | 
			
		||||
	return m.hash.Sum64(), nil
 | 
			
		||||
	return h, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MetricVec) hashLabels(labels Labels) (uint64, error) {
 | 
			
		||||
	if len(labels) != len(m.desc.variableLabels) {
 | 
			
		||||
		return 0, errInconsistentCardinality
 | 
			
		||||
	}
 | 
			
		||||
	m.hash.Reset()
 | 
			
		||||
	h := hashNew()
 | 
			
		||||
	for _, label := range m.desc.variableLabels {
 | 
			
		||||
		val, ok := labels[label]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return 0, fmt.Errorf("label name %q missing in label map", label)
 | 
			
		||||
		}
 | 
			
		||||
		m.buf.Reset()
 | 
			
		||||
		m.buf.WriteString(val)
 | 
			
		||||
		m.hash.Write(m.buf.Bytes())
 | 
			
		||||
		h = m.hashAdd(h, val)
 | 
			
		||||
		h = m.hashAddByte(h, model.SeparatorByte)
 | 
			
		||||
	}
 | 
			
		||||
	return m.hash.Sum64(), nil
 | 
			
		||||
	return h, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MetricVec) getOrCreateMetric(hash uint64, labelValues ...string) Metric {
 | 
			
		||||
	metric, ok := m.children[hash]
 | 
			
		||||
// getOrCreateMetricWithLabelValues retrieves the metric by hash and label value
 | 
			
		||||
// or creates it and returns the new one.
 | 
			
		||||
//
 | 
			
		||||
// This function holds the mutex.
 | 
			
		||||
func (m *MetricVec) getOrCreateMetricWithLabelValues(hash uint64, lvs []string) Metric {
 | 
			
		||||
	m.mtx.RLock()
 | 
			
		||||
	metric, ok := m.getMetricWithLabelValues(hash, lvs)
 | 
			
		||||
	m.mtx.RUnlock()
 | 
			
		||||
	if ok {
 | 
			
		||||
		return metric
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.mtx.Lock()
 | 
			
		||||
	defer m.mtx.Unlock()
 | 
			
		||||
	metric, ok = m.getMetricWithLabelValues(hash, lvs)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		// Copy labelValues. Otherwise, they would be allocated even if we don't go
 | 
			
		||||
		// down this code path.
 | 
			
		||||
		copiedLabelValues := append(make([]string, 0, len(labelValues)), labelValues...)
 | 
			
		||||
		metric = m.newMetric(copiedLabelValues...)
 | 
			
		||||
		m.children[hash] = metric
 | 
			
		||||
		// Copy to avoid allocation in case wo don't go down this code path.
 | 
			
		||||
		copiedLVs := make([]string, len(lvs))
 | 
			
		||||
		copy(copiedLVs, lvs)
 | 
			
		||||
		metric = m.newMetric(copiedLVs...)
 | 
			
		||||
		m.children[hash] = append(m.children[hash], metricWithLabelValues{values: copiedLVs, metric: metric})
 | 
			
		||||
	}
 | 
			
		||||
	return metric
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getOrCreateMetricWithLabelValues retrieves the metric by hash and label value
 | 
			
		||||
// or creates it and returns the new one.
 | 
			
		||||
//
 | 
			
		||||
// This function holds the mutex.
 | 
			
		||||
func (m *MetricVec) getOrCreateMetricWithLabels(hash uint64, labels Labels) Metric {
 | 
			
		||||
	m.mtx.RLock()
 | 
			
		||||
	metric, ok := m.getMetricWithLabels(hash, labels)
 | 
			
		||||
	m.mtx.RUnlock()
 | 
			
		||||
	if ok {
 | 
			
		||||
		return metric
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m.mtx.Lock()
 | 
			
		||||
	defer m.mtx.Unlock()
 | 
			
		||||
	metric, ok = m.getMetricWithLabels(hash, labels)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		lvs := m.extractLabelValues(labels)
 | 
			
		||||
		metric = m.newMetric(lvs...)
 | 
			
		||||
		m.children[hash] = append(m.children[hash], metricWithLabelValues{values: lvs, metric: metric})
 | 
			
		||||
	}
 | 
			
		||||
	return metric
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getMetricWithLabelValues gets a metric while handling possible collisions in
 | 
			
		||||
// the hash space. Must be called while holding read mutex.
 | 
			
		||||
func (m *MetricVec) getMetricWithLabelValues(h uint64, lvs []string) (Metric, bool) {
 | 
			
		||||
	metrics, ok := m.children[h]
 | 
			
		||||
	if ok {
 | 
			
		||||
		if i := m.findMetricWithLabelValues(metrics, lvs); i < len(metrics) {
 | 
			
		||||
			return metrics[i].metric, true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getMetricWithLabels gets a metric while handling possible collisions in
 | 
			
		||||
// the hash space. Must be called while holding read mutex.
 | 
			
		||||
func (m *MetricVec) getMetricWithLabels(h uint64, labels Labels) (Metric, bool) {
 | 
			
		||||
	metrics, ok := m.children[h]
 | 
			
		||||
	if ok {
 | 
			
		||||
		if i := m.findMetricWithLabels(metrics, labels); i < len(metrics) {
 | 
			
		||||
			return metrics[i].metric, true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// findMetricWithLabelValues returns the index of the matching metric or
 | 
			
		||||
// len(metrics) if not found.
 | 
			
		||||
func (m *MetricVec) findMetricWithLabelValues(metrics []metricWithLabelValues, lvs []string) int {
 | 
			
		||||
	for i, metric := range metrics {
 | 
			
		||||
		if m.matchLabelValues(metric.values, lvs) {
 | 
			
		||||
			return i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return len(metrics)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// findMetricWithLabels returns the index of the matching metric or len(metrics)
 | 
			
		||||
// if not found.
 | 
			
		||||
func (m *MetricVec) findMetricWithLabels(metrics []metricWithLabelValues, labels Labels) int {
 | 
			
		||||
	for i, metric := range metrics {
 | 
			
		||||
		if m.matchLabels(metric.values, labels) {
 | 
			
		||||
			return i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return len(metrics)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MetricVec) matchLabelValues(values []string, lvs []string) bool {
 | 
			
		||||
	if len(values) != len(lvs) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	for i, v := range values {
 | 
			
		||||
		if v != lvs[i] {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MetricVec) matchLabels(values []string, labels Labels) bool {
 | 
			
		||||
	if len(labels) != len(values) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	for i, k := range m.desc.variableLabels {
 | 
			
		||||
		if values[i] != labels[k] {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MetricVec) extractLabelValues(labels Labels) []string {
 | 
			
		||||
	labelValues := make([]string, len(labels))
 | 
			
		||||
	for i, k := range m.desc.variableLabels {
 | 
			
		||||
		labelValues[i] = labels[k]
 | 
			
		||||
	}
 | 
			
		||||
	return labelValues
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								vendor/github.com/prometheus/common/AUTHORS.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/prometheus/common/AUTHORS.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,11 +0,0 @@
 | 
			
		||||
Maintainers of this repository:
 | 
			
		||||
 | 
			
		||||
* Fabian Reinartz <fabian@soundcloud.com>
 | 
			
		||||
 | 
			
		||||
The following individuals have contributed code to this repository
 | 
			
		||||
(listed in alphabetical order):
 | 
			
		||||
 | 
			
		||||
* Björn Rabenstein <beorn@soundcloud.com>
 | 
			
		||||
* Fabian Reinartz <fabian@soundcloud.com>
 | 
			
		||||
* Julius Volz <julius@soundcloud.com>
 | 
			
		||||
* Miguel Molina <hi@mvader.me>
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/github.com/prometheus/common/expfmt/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/prometheus/common/expfmt/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -13,16 +13,15 @@ go_library(
 | 
			
		||||
        "decode.go",
 | 
			
		||||
        "encode.go",
 | 
			
		||||
        "expfmt.go",
 | 
			
		||||
        "json_decode.go",
 | 
			
		||||
        "text_create.go",
 | 
			
		||||
        "text_parse.go",
 | 
			
		||||
    ],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//vendor/bitbucket.org/ww/goautoneg:go_default_library",
 | 
			
		||||
        "//vendor/github.com/golang/protobuf/proto:go_default_library",
 | 
			
		||||
        "//vendor/github.com/matttproud/golang_protobuf_extensions/pbutil:go_default_library",
 | 
			
		||||
        "//vendor/github.com/prometheus/client_model/go:go_default_library",
 | 
			
		||||
        "//vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg:go_default_library",
 | 
			
		||||
        "//vendor/github.com/prometheus/common/model:go_default_library",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										96
									
								
								vendor/github.com/prometheus/common/expfmt/decode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										96
									
								
								vendor/github.com/prometheus/common/expfmt/decode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -31,6 +31,7 @@ type Decoder interface {
 | 
			
		||||
	Decode(*dto.MetricFamily) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DecodeOptions contains options used by the Decoder and in sample extraction.
 | 
			
		||||
type DecodeOptions struct {
 | 
			
		||||
	// Timestamp is added to each value from the stream that has no explicit timestamp set.
 | 
			
		||||
	Timestamp model.Time
 | 
			
		||||
@@ -46,10 +47,7 @@ func ResponseFormat(h http.Header) Format {
 | 
			
		||||
		return FmtUnknown
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const (
 | 
			
		||||
		textType = "text/plain"
 | 
			
		||||
		jsonType = "application/json"
 | 
			
		||||
	)
 | 
			
		||||
	const textType = "text/plain"
 | 
			
		||||
 | 
			
		||||
	switch mediatype {
 | 
			
		||||
	case ProtoType:
 | 
			
		||||
@@ -66,22 +64,6 @@ func ResponseFormat(h http.Header) Format {
 | 
			
		||||
			return FmtUnknown
 | 
			
		||||
		}
 | 
			
		||||
		return FmtText
 | 
			
		||||
 | 
			
		||||
	case jsonType:
 | 
			
		||||
		var prometheusAPIVersion string
 | 
			
		||||
 | 
			
		||||
		if params["schema"] == "prometheus/telemetry" && params["version"] != "" {
 | 
			
		||||
			prometheusAPIVersion = params["version"]
 | 
			
		||||
		} else {
 | 
			
		||||
			prometheusAPIVersion = h.Get("X-Prometheus-API-Version")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch prometheusAPIVersion {
 | 
			
		||||
		case "0.0.2", "":
 | 
			
		||||
			return fmtJSON2
 | 
			
		||||
		default:
 | 
			
		||||
			return FmtUnknown
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return FmtUnknown
 | 
			
		||||
@@ -93,8 +75,6 @@ func NewDecoder(r io.Reader, format Format) Decoder {
 | 
			
		||||
	switch format {
 | 
			
		||||
	case FmtProtoDelim:
 | 
			
		||||
		return &protoDecoder{r: r}
 | 
			
		||||
	case fmtJSON2:
 | 
			
		||||
		return newJSON2Decoder(r)
 | 
			
		||||
	}
 | 
			
		||||
	return &textDecoder{r: r}
 | 
			
		||||
}
 | 
			
		||||
@@ -107,10 +87,32 @@ type protoDecoder struct {
 | 
			
		||||
// Decode implements the Decoder interface.
 | 
			
		||||
func (d *protoDecoder) Decode(v *dto.MetricFamily) error {
 | 
			
		||||
	_, err := pbutil.ReadDelimited(d.r, v)
 | 
			
		||||
	return err
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if !model.IsValidMetricName(model.LabelValue(v.GetName())) {
 | 
			
		||||
		return fmt.Errorf("invalid metric name %q", v.GetName())
 | 
			
		||||
	}
 | 
			
		||||
	for _, m := range v.GetMetric() {
 | 
			
		||||
		if m == nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		for _, l := range m.GetLabel() {
 | 
			
		||||
			if l == nil {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if !model.LabelValue(l.GetValue()).IsValid() {
 | 
			
		||||
				return fmt.Errorf("invalid label value %q", l.GetValue())
 | 
			
		||||
			}
 | 
			
		||||
			if !model.LabelName(l.GetName()).IsValid() {
 | 
			
		||||
				return fmt.Errorf("invalid label name %q", l.GetName())
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// textDecoder implements the Decoder interface for the text protcol.
 | 
			
		||||
// textDecoder implements the Decoder interface for the text protocol.
 | 
			
		||||
type textDecoder struct {
 | 
			
		||||
	r    io.Reader
 | 
			
		||||
	p    TextParser
 | 
			
		||||
@@ -141,6 +143,8 @@ func (d *textDecoder) Decode(v *dto.MetricFamily) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SampleDecoder wraps a Decoder to extract samples from the metric families
 | 
			
		||||
// decoded by the wrapped Decoder.
 | 
			
		||||
type SampleDecoder struct {
 | 
			
		||||
	Dec  Decoder
 | 
			
		||||
	Opts *DecodeOptions
 | 
			
		||||
@@ -148,37 +152,51 @@ type SampleDecoder struct {
 | 
			
		||||
	f dto.MetricFamily
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Decode calls the Decode method of the wrapped Decoder and then extracts the
 | 
			
		||||
// samples from the decoded MetricFamily into the provided model.Vector.
 | 
			
		||||
func (sd *SampleDecoder) Decode(s *model.Vector) error {
 | 
			
		||||
	if err := sd.Dec.Decode(&sd.f); err != nil {
 | 
			
		||||
	err := sd.Dec.Decode(&sd.f)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	*s = extractSamples(&sd.f, sd.Opts)
 | 
			
		||||
	return nil
 | 
			
		||||
	*s, err = extractSamples(&sd.f, sd.Opts)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Extract samples builds a slice of samples from the provided metric families.
 | 
			
		||||
func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) model.Vector {
 | 
			
		||||
	var all model.Vector
 | 
			
		||||
// ExtractSamples builds a slice of samples from the provided metric
 | 
			
		||||
// families. If an error occurs during sample extraction, it continues to
 | 
			
		||||
// extract from the remaining metric families. The returned error is the last
 | 
			
		||||
// error that has occured.
 | 
			
		||||
func ExtractSamples(o *DecodeOptions, fams ...*dto.MetricFamily) (model.Vector, error) {
 | 
			
		||||
	var (
 | 
			
		||||
		all     model.Vector
 | 
			
		||||
		lastErr error
 | 
			
		||||
	)
 | 
			
		||||
	for _, f := range fams {
 | 
			
		||||
		all = append(all, extractSamples(f, o)...)
 | 
			
		||||
		some, err := extractSamples(f, o)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			lastErr = err
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		all = append(all, some...)
 | 
			
		||||
	}
 | 
			
		||||
	return all
 | 
			
		||||
	return all, lastErr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func extractSamples(f *dto.MetricFamily, o *DecodeOptions) model.Vector {
 | 
			
		||||
func extractSamples(f *dto.MetricFamily, o *DecodeOptions) (model.Vector, error) {
 | 
			
		||||
	switch f.GetType() {
 | 
			
		||||
	case dto.MetricType_COUNTER:
 | 
			
		||||
		return extractCounter(o, f)
 | 
			
		||||
		return extractCounter(o, f), nil
 | 
			
		||||
	case dto.MetricType_GAUGE:
 | 
			
		||||
		return extractGauge(o, f)
 | 
			
		||||
		return extractGauge(o, f), nil
 | 
			
		||||
	case dto.MetricType_SUMMARY:
 | 
			
		||||
		return extractSummary(o, f)
 | 
			
		||||
		return extractSummary(o, f), nil
 | 
			
		||||
	case dto.MetricType_UNTYPED:
 | 
			
		||||
		return extractUntyped(o, f)
 | 
			
		||||
		return extractUntyped(o, f), nil
 | 
			
		||||
	case dto.MetricType_HISTOGRAM:
 | 
			
		||||
		return extractHistogram(o, f)
 | 
			
		||||
		return extractHistogram(o, f), nil
 | 
			
		||||
	}
 | 
			
		||||
	panic("expfmt.extractSamples: unknown metric family type")
 | 
			
		||||
	return nil, fmt.Errorf("expfmt.extractSamples: unknown metric family type %v", f.GetType())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func extractCounter(o *DecodeOptions, f *dto.MetricFamily) model.Vector {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/github.com/prometheus/common/expfmt/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/prometheus/common/expfmt/encode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -18,9 +18,9 @@ import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"bitbucket.org/ww/goautoneg"
 | 
			
		||||
	"github.com/golang/protobuf/proto"
 | 
			
		||||
	"github.com/matttproud/golang_protobuf_extensions/pbutil"
 | 
			
		||||
	"github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg"
 | 
			
		||||
 | 
			
		||||
	dto "github.com/prometheus/client_model/go"
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								vendor/github.com/prometheus/common/expfmt/expfmt.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/prometheus/common/expfmt/expfmt.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -11,14 +11,15 @@
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// A package for reading and writing Prometheus metrics.
 | 
			
		||||
// Package expfmt contains tools for reading and writing Prometheus metrics.
 | 
			
		||||
package expfmt
 | 
			
		||||
 | 
			
		||||
// Format specifies the HTTP content type of the different wire protocols.
 | 
			
		||||
type Format string
 | 
			
		||||
 | 
			
		||||
// Constants to assemble the Content-Type values for the different wire protocols.
 | 
			
		||||
const (
 | 
			
		||||
	TextVersion = "0.0.4"
 | 
			
		||||
 | 
			
		||||
	TextVersion   = "0.0.4"
 | 
			
		||||
	ProtoType     = `application/vnd.google.protobuf`
 | 
			
		||||
	ProtoProtocol = `io.prometheus.client.MetricFamily`
 | 
			
		||||
	ProtoFmt      = ProtoType + "; proto=" + ProtoProtocol + ";"
 | 
			
		||||
@@ -29,9 +30,6 @@ const (
 | 
			
		||||
	FmtProtoDelim   Format = ProtoFmt + ` encoding=delimited`
 | 
			
		||||
	FmtProtoText    Format = ProtoFmt + ` encoding=text`
 | 
			
		||||
	FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text`
 | 
			
		||||
 | 
			
		||||
	// fmtJSON2 is hidden as it is deprecated.
 | 
			
		||||
	fmtJSON2 Format = `application/json; version=0.0.2`
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/github.com/prometheus/common/expfmt/fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/prometheus/common/expfmt/fuzz.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -20,8 +20,8 @@ import "bytes"
 | 
			
		||||
 | 
			
		||||
// Fuzz text metric parser with with github.com/dvyukov/go-fuzz:
 | 
			
		||||
//
 | 
			
		||||
//     go-fuzz-build github.com/prometheus/client_golang/text
 | 
			
		||||
//     go-fuzz -bin text-fuzz.zip -workdir fuzz
 | 
			
		||||
//     go-fuzz-build github.com/prometheus/common/expfmt
 | 
			
		||||
//     go-fuzz -bin expfmt-fuzz.zip -workdir fuzz
 | 
			
		||||
//
 | 
			
		||||
// Further input samples should go in the folder fuzz/corpus.
 | 
			
		||||
func Fuzz(in []byte) int {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										162
									
								
								vendor/github.com/prometheus/common/expfmt/json_decode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										162
									
								
								vendor/github.com/prometheus/common/expfmt/json_decode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,162 +0,0 @@
 | 
			
		||||
// Copyright 2015 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package expfmt
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"sort"
 | 
			
		||||
 | 
			
		||||
	"github.com/golang/protobuf/proto"
 | 
			
		||||
	dto "github.com/prometheus/client_model/go"
 | 
			
		||||
 | 
			
		||||
	"github.com/prometheus/common/model"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type json2Decoder struct {
 | 
			
		||||
	dec  *json.Decoder
 | 
			
		||||
	fams []*dto.MetricFamily
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newJSON2Decoder(r io.Reader) Decoder {
 | 
			
		||||
	return &json2Decoder{
 | 
			
		||||
		dec: json.NewDecoder(r),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type histogram002 struct {
 | 
			
		||||
	Labels model.LabelSet     `json:"labels"`
 | 
			
		||||
	Values map[string]float64 `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type counter002 struct {
 | 
			
		||||
	Labels model.LabelSet `json:"labels"`
 | 
			
		||||
	Value  float64        `json:"value"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func protoLabelSet(base, ext model.LabelSet) []*dto.LabelPair {
 | 
			
		||||
	labels := base.Clone().Merge(ext)
 | 
			
		||||
	delete(labels, model.MetricNameLabel)
 | 
			
		||||
 | 
			
		||||
	names := make([]string, 0, len(labels))
 | 
			
		||||
	for ln := range labels {
 | 
			
		||||
		names = append(names, string(ln))
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(names)
 | 
			
		||||
 | 
			
		||||
	pairs := make([]*dto.LabelPair, 0, len(labels))
 | 
			
		||||
 | 
			
		||||
	for _, ln := range names {
 | 
			
		||||
		lv := labels[model.LabelName(ln)]
 | 
			
		||||
 | 
			
		||||
		pairs = append(pairs, &dto.LabelPair{
 | 
			
		||||
			Name:  proto.String(ln),
 | 
			
		||||
			Value: proto.String(string(lv)),
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pairs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *json2Decoder) more() error {
 | 
			
		||||
	var entities []struct {
 | 
			
		||||
		BaseLabels model.LabelSet `json:"baseLabels"`
 | 
			
		||||
		Docstring  string         `json:"docstring"`
 | 
			
		||||
		Metric     struct {
 | 
			
		||||
			Type   string          `json:"type"`
 | 
			
		||||
			Values json.RawMessage `json:"value"`
 | 
			
		||||
		} `json:"metric"`
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := d.dec.Decode(&entities); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	for _, e := range entities {
 | 
			
		||||
		f := &dto.MetricFamily{
 | 
			
		||||
			Name:   proto.String(string(e.BaseLabels[model.MetricNameLabel])),
 | 
			
		||||
			Help:   proto.String(e.Docstring),
 | 
			
		||||
			Type:   dto.MetricType_UNTYPED.Enum(),
 | 
			
		||||
			Metric: []*dto.Metric{},
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		d.fams = append(d.fams, f)
 | 
			
		||||
 | 
			
		||||
		switch e.Metric.Type {
 | 
			
		||||
		case "counter", "gauge":
 | 
			
		||||
			var values []counter002
 | 
			
		||||
 | 
			
		||||
			if err := json.Unmarshal(e.Metric.Values, &values); err != nil {
 | 
			
		||||
				return fmt.Errorf("could not extract %s value: %s", e.Metric.Type, err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for _, ctr := range values {
 | 
			
		||||
				f.Metric = append(f.Metric, &dto.Metric{
 | 
			
		||||
					Label: protoLabelSet(e.BaseLabels, ctr.Labels),
 | 
			
		||||
					Untyped: &dto.Untyped{
 | 
			
		||||
						Value: proto.Float64(ctr.Value),
 | 
			
		||||
					},
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		case "histogram":
 | 
			
		||||
			var values []histogram002
 | 
			
		||||
 | 
			
		||||
			if err := json.Unmarshal(e.Metric.Values, &values); err != nil {
 | 
			
		||||
				return fmt.Errorf("could not extract %s value: %s", e.Metric.Type, err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for _, hist := range values {
 | 
			
		||||
				quants := make([]string, 0, len(values))
 | 
			
		||||
				for q := range hist.Values {
 | 
			
		||||
					quants = append(quants, q)
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				sort.Strings(quants)
 | 
			
		||||
 | 
			
		||||
				for _, q := range quants {
 | 
			
		||||
					value := hist.Values[q]
 | 
			
		||||
					// The correct label is "quantile" but to not break old expressions
 | 
			
		||||
					// this remains "percentile"
 | 
			
		||||
					hist.Labels["percentile"] = model.LabelValue(q)
 | 
			
		||||
 | 
			
		||||
					f.Metric = append(f.Metric, &dto.Metric{
 | 
			
		||||
						Label: protoLabelSet(e.BaseLabels, hist.Labels),
 | 
			
		||||
						Untyped: &dto.Untyped{
 | 
			
		||||
							Value: proto.Float64(value),
 | 
			
		||||
						},
 | 
			
		||||
					})
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			return fmt.Errorf("unknown metric type %q", e.Metric.Type)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Decode implements the Decoder interface.
 | 
			
		||||
func (d *json2Decoder) Decode(v *dto.MetricFamily) error {
 | 
			
		||||
	if len(d.fams) == 0 {
 | 
			
		||||
		if err := d.more(); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*v = *d.fams[0]
 | 
			
		||||
	d.fams = d.fams[1:]
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								vendor/github.com/prometheus/common/expfmt/text_create.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/prometheus/common/expfmt/text_create.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -14,7 +14,6 @@
 | 
			
		||||
package expfmt
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"math"
 | 
			
		||||
@@ -26,9 +25,12 @@ import (
 | 
			
		||||
 | 
			
		||||
// MetricFamilyToText converts a MetricFamily proto message into text format and
 | 
			
		||||
// writes the resulting lines to 'out'. It returns the number of bytes written
 | 
			
		||||
// and any error encountered.  This function does not perform checks on the
 | 
			
		||||
// content of the metric and label names, i.e. invalid metric or label names
 | 
			
		||||
// and any error encountered. The output will have the same order as the input,
 | 
			
		||||
// no further sorting is performed. Furthermore, this function assumes the input
 | 
			
		||||
// is already sanitized and does not perform any sanity checks. If the input
 | 
			
		||||
// contains duplicate metrics or invalid metric or label names, the conversion
 | 
			
		||||
// will result in invalid text format output.
 | 
			
		||||
//
 | 
			
		||||
// This method fulfills the type 'prometheus.encoder'.
 | 
			
		||||
func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
 | 
			
		||||
	var written int
 | 
			
		||||
@@ -285,21 +287,17 @@ func labelPairsToText(
 | 
			
		||||
	return written, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	escape                = strings.NewReplacer("\\", `\\`, "\n", `\n`)
 | 
			
		||||
	escapeWithDoubleQuote = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// escapeString replaces '\' by '\\', new line character by '\n', and - if
 | 
			
		||||
// includeDoubleQuote is true - '"' by '\"'.
 | 
			
		||||
func escapeString(v string, includeDoubleQuote bool) string {
 | 
			
		||||
	result := bytes.NewBuffer(make([]byte, 0, len(v)))
 | 
			
		||||
	for _, c := range v {
 | 
			
		||||
		switch {
 | 
			
		||||
		case c == '\\':
 | 
			
		||||
			result.WriteString(`\\`)
 | 
			
		||||
		case includeDoubleQuote && c == '"':
 | 
			
		||||
			result.WriteString(`\"`)
 | 
			
		||||
		case c == '\n':
 | 
			
		||||
			result.WriteString(`\n`)
 | 
			
		||||
		default:
 | 
			
		||||
			result.WriteRune(c)
 | 
			
		||||
		}
 | 
			
		||||
	if includeDoubleQuote {
 | 
			
		||||
		return escapeWithDoubleQuote.Replace(v)
 | 
			
		||||
	}
 | 
			
		||||
	return result.String()
 | 
			
		||||
 | 
			
		||||
	return escape.Replace(v)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/github.com/prometheus/common/expfmt/text_parse.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/prometheus/common/expfmt/text_parse.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -47,7 +47,7 @@ func (e ParseError) Error() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TextParser is used to parse the simple and flat text-based exchange format. Its
 | 
			
		||||
// nil value is ready to use.
 | 
			
		||||
// zero value is ready to use.
 | 
			
		||||
type TextParser struct {
 | 
			
		||||
	metricFamiliesByName map[string]*dto.MetricFamily
 | 
			
		||||
	buf                  *bufio.Reader // Where the parsed input is read through.
 | 
			
		||||
@@ -108,6 +108,13 @@ func (p *TextParser) TextToMetricFamilies(in io.Reader) (map[string]*dto.MetricF
 | 
			
		||||
			delete(p.metricFamiliesByName, k)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// If p.err is io.EOF now, we have run into a premature end of the input
 | 
			
		||||
	// stream. Turn this error into something nicer and more
 | 
			
		||||
	// meaningful. (io.EOF is often used as a signal for the legitimate end
 | 
			
		||||
	// of an input stream.)
 | 
			
		||||
	if p.err == io.EOF {
 | 
			
		||||
		p.parseError("unexpected end of input stream")
 | 
			
		||||
	}
 | 
			
		||||
	return p.metricFamiliesByName, p.err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,17 @@ package(default_visibility = ["//visibility:public"])
 | 
			
		||||
 | 
			
		||||
licenses(["notice"])
 | 
			
		||||
 | 
			
		||||
load(
 | 
			
		||||
    "@io_bazel_rules_go//go:def.bzl",
 | 
			
		||||
    "go_library",
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = ["autoneg.go"],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
    name = "package-srcs",
 | 
			
		||||
    srcs = glob(["**"]),
 | 
			
		||||
							
								
								
									
										67
									
								
								vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/README.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
PACKAGE
 | 
			
		||||
 | 
			
		||||
package goautoneg
 | 
			
		||||
import "bitbucket.org/ww/goautoneg"
 | 
			
		||||
 | 
			
		||||
HTTP Content-Type Autonegotiation.
 | 
			
		||||
 | 
			
		||||
The functions in this package implement the behaviour specified in
 | 
			
		||||
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2011, Open Knowledge Foundation Ltd.
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are
 | 
			
		||||
met:
 | 
			
		||||
 | 
			
		||||
    Redistributions of source code must retain the above copyright
 | 
			
		||||
    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
    Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
    notice, this list of conditions and the following disclaimer in
 | 
			
		||||
    the documentation and/or other materials provided with the
 | 
			
		||||
    distribution.
 | 
			
		||||
 | 
			
		||||
    Neither the name of the Open Knowledge Foundation Ltd. nor the
 | 
			
		||||
    names of its contributors may be used to endorse or promote
 | 
			
		||||
    products derived from this software without specific prior written
 | 
			
		||||
    permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
FUNCTIONS
 | 
			
		||||
 | 
			
		||||
func Negotiate(header string, alternatives []string) (content_type string)
 | 
			
		||||
Negotiate the most appropriate content_type given the accept header
 | 
			
		||||
and a list of alternatives.
 | 
			
		||||
 | 
			
		||||
func ParseAccept(header string) (accept []Accept)
 | 
			
		||||
Parse an Accept Header string returning a sorted list
 | 
			
		||||
of clauses
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TYPES
 | 
			
		||||
 | 
			
		||||
type Accept struct {
 | 
			
		||||
    Type, SubType string
 | 
			
		||||
    Q             float32
 | 
			
		||||
    Params        map[string]string
 | 
			
		||||
}
 | 
			
		||||
Structure to represent a clause in an HTTP Accept Header
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SUBDIRECTORIES
 | 
			
		||||
 | 
			
		||||
	.hg
 | 
			
		||||
							
								
								
									
										162
									
								
								vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								vendor/github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg/autoneg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,162 @@
 | 
			
		||||
/*
 | 
			
		||||
HTTP Content-Type Autonegotiation.
 | 
			
		||||
 | 
			
		||||
The functions in this package implement the behaviour specified in
 | 
			
		||||
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2011, Open Knowledge Foundation Ltd.
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are
 | 
			
		||||
met:
 | 
			
		||||
 | 
			
		||||
    Redistributions of source code must retain the above copyright
 | 
			
		||||
    notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
    Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
    notice, this list of conditions and the following disclaimer in
 | 
			
		||||
    the documentation and/or other materials provided with the
 | 
			
		||||
    distribution.
 | 
			
		||||
 | 
			
		||||
    Neither the name of the Open Knowledge Foundation Ltd. nor the
 | 
			
		||||
    names of its contributors may be used to endorse or promote
 | 
			
		||||
    products derived from this software without specific prior written
 | 
			
		||||
    permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
package goautoneg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Structure to represent a clause in an HTTP Accept Header
 | 
			
		||||
type Accept struct {
 | 
			
		||||
	Type, SubType string
 | 
			
		||||
	Q             float64
 | 
			
		||||
	Params        map[string]string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// For internal use, so that we can use the sort interface
 | 
			
		||||
type accept_slice []Accept
 | 
			
		||||
 | 
			
		||||
func (accept accept_slice) Len() int {
 | 
			
		||||
	slice := []Accept(accept)
 | 
			
		||||
	return len(slice)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (accept accept_slice) Less(i, j int) bool {
 | 
			
		||||
	slice := []Accept(accept)
 | 
			
		||||
	ai, aj := slice[i], slice[j]
 | 
			
		||||
	if ai.Q > aj.Q {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	if ai.Type != "*" && aj.Type == "*" {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	if ai.SubType != "*" && aj.SubType == "*" {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (accept accept_slice) Swap(i, j int) {
 | 
			
		||||
	slice := []Accept(accept)
 | 
			
		||||
	slice[i], slice[j] = slice[j], slice[i]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Parse an Accept Header string returning a sorted list
 | 
			
		||||
// of clauses
 | 
			
		||||
func ParseAccept(header string) (accept []Accept) {
 | 
			
		||||
	parts := strings.Split(header, ",")
 | 
			
		||||
	accept = make([]Accept, 0, len(parts))
 | 
			
		||||
	for _, part := range parts {
 | 
			
		||||
		part := strings.Trim(part, " ")
 | 
			
		||||
 | 
			
		||||
		a := Accept{}
 | 
			
		||||
		a.Params = make(map[string]string)
 | 
			
		||||
		a.Q = 1.0
 | 
			
		||||
 | 
			
		||||
		mrp := strings.Split(part, ";")
 | 
			
		||||
 | 
			
		||||
		media_range := mrp[0]
 | 
			
		||||
		sp := strings.Split(media_range, "/")
 | 
			
		||||
		a.Type = strings.Trim(sp[0], " ")
 | 
			
		||||
 | 
			
		||||
		switch {
 | 
			
		||||
		case len(sp) == 1 && a.Type == "*":
 | 
			
		||||
			a.SubType = "*"
 | 
			
		||||
		case len(sp) == 2:
 | 
			
		||||
			a.SubType = strings.Trim(sp[1], " ")
 | 
			
		||||
		default:
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(mrp) == 1 {
 | 
			
		||||
			accept = append(accept, a)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, param := range mrp[1:] {
 | 
			
		||||
			sp := strings.SplitN(param, "=", 2)
 | 
			
		||||
			if len(sp) != 2 {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			token := strings.Trim(sp[0], " ")
 | 
			
		||||
			if token == "q" {
 | 
			
		||||
				a.Q, _ = strconv.ParseFloat(sp[1], 32)
 | 
			
		||||
			} else {
 | 
			
		||||
				a.Params[token] = strings.Trim(sp[1], " ")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		accept = append(accept, a)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	slice := accept_slice(accept)
 | 
			
		||||
	sort.Sort(slice)
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Negotiate the most appropriate content_type given the accept header
 | 
			
		||||
// and a list of alternatives.
 | 
			
		||||
func Negotiate(header string, alternatives []string) (content_type string) {
 | 
			
		||||
	asp := make([][]string, 0, len(alternatives))
 | 
			
		||||
	for _, ctype := range alternatives {
 | 
			
		||||
		asp = append(asp, strings.SplitN(ctype, "/", 2))
 | 
			
		||||
	}
 | 
			
		||||
	for _, clause := range ParseAccept(header) {
 | 
			
		||||
		for i, ctsp := range asp {
 | 
			
		||||
			if clause.Type == ctsp[0] && clause.SubType == ctsp[1] {
 | 
			
		||||
				content_type = alternatives[i]
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			if clause.Type == ctsp[0] && clause.SubType == "*" {
 | 
			
		||||
				content_type = alternatives[i]
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			if clause.Type == "*" && clause.SubType == "*" {
 | 
			
		||||
				content_type = alternatives[i]
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/prometheus/common/model/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/prometheus/common/model/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -12,6 +12,7 @@ go_library(
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "alert.go",
 | 
			
		||||
        "fingerprinting.go",
 | 
			
		||||
        "fnv.go",
 | 
			
		||||
        "labels.go",
 | 
			
		||||
        "labelset.go",
 | 
			
		||||
        "metric.go",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								vendor/github.com/prometheus/common/model/alert.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								vendor/github.com/prometheus/common/model/alert.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -35,8 +35,9 @@ type Alert struct {
 | 
			
		||||
	Annotations LabelSet `json:"annotations"`
 | 
			
		||||
 | 
			
		||||
	// The known time range for this alert. Both ends are optional.
 | 
			
		||||
	StartsAt time.Time `json:"startsAt,omitempty"`
 | 
			
		||||
	EndsAt   time.Time `json:"endsAt,omitempty"`
 | 
			
		||||
	StartsAt     time.Time `json:"startsAt,omitempty"`
 | 
			
		||||
	EndsAt       time.Time `json:"endsAt,omitempty"`
 | 
			
		||||
	GeneratorURL string    `json:"generatorURL"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Name returns the name of the alert. It is equivalent to the "alertname" label.
 | 
			
		||||
@@ -60,10 +61,16 @@ func (a *Alert) String() string {
 | 
			
		||||
 | 
			
		||||
// Resolved returns true iff the activity interval ended in the past.
 | 
			
		||||
func (a *Alert) Resolved() bool {
 | 
			
		||||
	return a.ResolvedAt(time.Now())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ResolvedAt returns true off the activity interval ended before
 | 
			
		||||
// the given timestamp.
 | 
			
		||||
func (a *Alert) ResolvedAt(ts time.Time) bool {
 | 
			
		||||
	if a.EndsAt.IsZero() {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return !a.EndsAt.After(time.Now())
 | 
			
		||||
	return !a.EndsAt.After(ts)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Status returns the status of the alert.
 | 
			
		||||
@@ -74,6 +81,26 @@ func (a *Alert) Status() AlertStatus {
 | 
			
		||||
	return AlertFiring
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate checks whether the alert data is inconsistent.
 | 
			
		||||
func (a *Alert) Validate() error {
 | 
			
		||||
	if a.StartsAt.IsZero() {
 | 
			
		||||
		return fmt.Errorf("start time missing")
 | 
			
		||||
	}
 | 
			
		||||
	if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) {
 | 
			
		||||
		return fmt.Errorf("start time must be before end time")
 | 
			
		||||
	}
 | 
			
		||||
	if err := a.Labels.Validate(); err != nil {
 | 
			
		||||
		return fmt.Errorf("invalid label set: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	if len(a.Labels) == 0 {
 | 
			
		||||
		return fmt.Errorf("at least one label pair required")
 | 
			
		||||
	}
 | 
			
		||||
	if err := a.Annotations.Validate(); err != nil {
 | 
			
		||||
		return fmt.Errorf("invalid annotations: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Alert is a list of alerts that can be sorted in chronological order.
 | 
			
		||||
type Alerts []*Alert
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										42
									
								
								vendor/github.com/prometheus/common/model/fnv.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/prometheus/common/model/fnv.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
// Copyright 2015 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package model
 | 
			
		||||
 | 
			
		||||
// Inline and byte-free variant of hash/fnv's fnv64a.
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	offset64 = 14695981039346656037
 | 
			
		||||
	prime64  = 1099511628211
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// hashNew initializies a new fnv64a hash value.
 | 
			
		||||
func hashNew() uint64 {
 | 
			
		||||
	return offset64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// hashAdd adds a string to a fnv64a hash value, returning the updated hash.
 | 
			
		||||
func hashAdd(h uint64, s string) uint64 {
 | 
			
		||||
	for i := 0; i < len(s); i++ {
 | 
			
		||||
		h ^= uint64(s[i])
 | 
			
		||||
		h *= prime64
 | 
			
		||||
	}
 | 
			
		||||
	return h
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.
 | 
			
		||||
func hashAddByte(h uint64, b byte) uint64 {
 | 
			
		||||
	h ^= uint64(b)
 | 
			
		||||
	h *= prime64
 | 
			
		||||
	return h
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										32
									
								
								vendor/github.com/prometheus/common/model/labels.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/prometheus/common/model/labels.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -17,8 +17,8 @@ import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@@ -80,20 +80,37 @@ const (
 | 
			
		||||
	QuantileLabel = "quantile"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// LabelNameRE is a regular expression matching valid label names.
 | 
			
		||||
// LabelNameRE is a regular expression matching valid label names. Note that the
 | 
			
		||||
// IsValid method of LabelName performs the same check but faster than a match
 | 
			
		||||
// with this regular expression.
 | 
			
		||||
var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
 | 
			
		||||
 | 
			
		||||
// A LabelName is a key for a LabelSet or Metric.  It has a value associated
 | 
			
		||||
// therewith.
 | 
			
		||||
type LabelName string
 | 
			
		||||
 | 
			
		||||
// IsValid is true iff the label name matches the pattern of LabelNameRE. This
 | 
			
		||||
// method, however, does not use LabelNameRE for the check but a much faster
 | 
			
		||||
// hardcoded implementation.
 | 
			
		||||
func (ln LabelName) IsValid() bool {
 | 
			
		||||
	if len(ln) == 0 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	for i, b := range ln {
 | 
			
		||||
		if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UnmarshalYAML implements the yaml.Unmarshaler interface.
 | 
			
		||||
func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error {
 | 
			
		||||
	var s string
 | 
			
		||||
	if err := unmarshal(&s); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if !LabelNameRE.MatchString(s) {
 | 
			
		||||
	if !LabelName(s).IsValid() {
 | 
			
		||||
		return fmt.Errorf("%q is not a valid label name", s)
 | 
			
		||||
	}
 | 
			
		||||
	*ln = LabelName(s)
 | 
			
		||||
@@ -106,7 +123,7 @@ func (ln *LabelName) UnmarshalJSON(b []byte) error {
 | 
			
		||||
	if err := json.Unmarshal(b, &s); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if !LabelNameRE.MatchString(s) {
 | 
			
		||||
	if !LabelName(s).IsValid() {
 | 
			
		||||
		return fmt.Errorf("%q is not a valid label name", s)
 | 
			
		||||
	}
 | 
			
		||||
	*ln = LabelName(s)
 | 
			
		||||
@@ -139,6 +156,11 @@ func (l LabelNames) String() string {
 | 
			
		||||
// A LabelValue is an associated value for a LabelName.
 | 
			
		||||
type LabelValue string
 | 
			
		||||
 | 
			
		||||
// IsValid returns true iff the string is a valid UTF8.
 | 
			
		||||
func (lv LabelValue) IsValid() bool {
 | 
			
		||||
	return utf8.ValidString(string(lv))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LabelValues is a sortable LabelValue slice. It implements sort.Interface.
 | 
			
		||||
type LabelValues []LabelValue
 | 
			
		||||
 | 
			
		||||
@@ -147,7 +169,7 @@ func (l LabelValues) Len() int {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l LabelValues) Less(i, j int) bool {
 | 
			
		||||
	return sort.StringsAreSorted([]string{string(l[i]), string(l[j])})
 | 
			
		||||
	return string(l[i]) < string(l[j])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l LabelValues) Swap(i, j int) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								vendor/github.com/prometheus/common/model/labelset.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/prometheus/common/model/labelset.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -27,6 +27,21 @@ import (
 | 
			
		||||
// match.
 | 
			
		||||
type LabelSet map[LabelName]LabelValue
 | 
			
		||||
 | 
			
		||||
// Validate checks whether all names and values in the label set
 | 
			
		||||
// are valid.
 | 
			
		||||
func (ls LabelSet) Validate() error {
 | 
			
		||||
	for ln, lv := range ls {
 | 
			
		||||
		if !ln.IsValid() {
 | 
			
		||||
			return fmt.Errorf("invalid name %q", ln)
 | 
			
		||||
		}
 | 
			
		||||
		if !lv.IsValid() {
 | 
			
		||||
			return fmt.Errorf("invalid value %q", lv)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equal returns true iff both label sets have exactly the same key/value pairs.
 | 
			
		||||
func (ls LabelSet) Equal(o LabelSet) bool {
 | 
			
		||||
	if len(ls) != len(o) {
 | 
			
		||||
		return false
 | 
			
		||||
@@ -90,6 +105,7 @@ func (ls LabelSet) Before(o LabelSet) bool {
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Clone returns a copy of the label set.
 | 
			
		||||
func (ls LabelSet) Clone() LabelSet {
 | 
			
		||||
	lsn := make(LabelSet, len(ls))
 | 
			
		||||
	for ln, lv := range ls {
 | 
			
		||||
@@ -144,7 +160,7 @@ func (l *LabelSet) UnmarshalJSON(b []byte) error {
 | 
			
		||||
	// LabelName as a string and does not call its UnmarshalJSON method.
 | 
			
		||||
	// Thus, we have to replicate the behavior here.
 | 
			
		||||
	for ln := range m {
 | 
			
		||||
		if !LabelNameRE.MatchString(string(ln)) {
 | 
			
		||||
		if !ln.IsValid() {
 | 
			
		||||
			return fmt.Errorf("%q is not a valid label name", ln)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/github.com/prometheus/common/model/metric.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/prometheus/common/model/metric.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -15,11 +15,18 @@ package model
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var separator = []byte{0}
 | 
			
		||||
var (
 | 
			
		||||
	separator = []byte{0}
 | 
			
		||||
	// MetricNameRE is a regular expression matching valid metric
 | 
			
		||||
	// names. Note that the IsValidMetricName function performs the same
 | 
			
		||||
	// check but faster than a match with this regular expression.
 | 
			
		||||
	MetricNameRE = regexp.MustCompile(`^[a-zA-Z_:][a-zA-Z0-9_:]*$`)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A Metric is similar to a LabelSet, but the key difference is that a Metric is
 | 
			
		||||
// a singleton and refers to one and only one stream of samples.
 | 
			
		||||
@@ -37,7 +44,7 @@ func (m Metric) Before(o Metric) bool {
 | 
			
		||||
 | 
			
		||||
// Clone returns a copy of the Metric.
 | 
			
		||||
func (m Metric) Clone() Metric {
 | 
			
		||||
	clone := Metric{}
 | 
			
		||||
	clone := make(Metric, len(m))
 | 
			
		||||
	for k, v := range m {
 | 
			
		||||
		clone[k] = v
 | 
			
		||||
	}
 | 
			
		||||
@@ -79,3 +86,18 @@ func (m Metric) Fingerprint() Fingerprint {
 | 
			
		||||
func (m Metric) FastFingerprint() Fingerprint {
 | 
			
		||||
	return LabelSet(m).FastFingerprint()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsValidMetricName returns true iff name matches the pattern of MetricNameRE.
 | 
			
		||||
// This function, however, does not use MetricNameRE for the check but a much
 | 
			
		||||
// faster hardcoded implementation.
 | 
			
		||||
func IsValidMetricName(n LabelValue) bool {
 | 
			
		||||
	if len(n) == 0 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	for i, b := range n {
 | 
			
		||||
		if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == ':' || (b >= '0' && b <= '9' && i > 0)) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/github.com/prometheus/common/model/model.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/prometheus/common/model/model.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -12,5 +12,5 @@
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
// Package model contains common data structures that are shared across
 | 
			
		||||
// Prometheus componenets and libraries.
 | 
			
		||||
// Prometheus components and libraries.
 | 
			
		||||
package model
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										108
									
								
								vendor/github.com/prometheus/common/model/signature.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										108
									
								
								vendor/github.com/prometheus/common/model/signature.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -14,11 +14,7 @@
 | 
			
		||||
package model
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"hash"
 | 
			
		||||
	"hash/fnv"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is
 | 
			
		||||
@@ -28,30 +24,9 @@ const SeparatorByte byte = 255
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// cache the signature of an empty label set.
 | 
			
		||||
	emptyLabelSignature = fnv.New64a().Sum64()
 | 
			
		||||
 | 
			
		||||
	hashAndBufPool sync.Pool
 | 
			
		||||
	emptyLabelSignature = hashNew()
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type hashAndBuf struct {
 | 
			
		||||
	h hash.Hash64
 | 
			
		||||
	b bytes.Buffer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getHashAndBuf() *hashAndBuf {
 | 
			
		||||
	hb := hashAndBufPool.Get()
 | 
			
		||||
	if hb == nil {
 | 
			
		||||
		return &hashAndBuf{h: fnv.New64a()}
 | 
			
		||||
	}
 | 
			
		||||
	return hb.(*hashAndBuf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func putHashAndBuf(hb *hashAndBuf) {
 | 
			
		||||
	hb.h.Reset()
 | 
			
		||||
	hb.b.Reset()
 | 
			
		||||
	hashAndBufPool.Put(hb)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a
 | 
			
		||||
// given label set. (Collisions are possible but unlikely if the number of label
 | 
			
		||||
// sets the function is applied to is small.)
 | 
			
		||||
@@ -66,18 +41,14 @@ func LabelsToSignature(labels map[string]string) uint64 {
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(labelNames)
 | 
			
		||||
 | 
			
		||||
	hb := getHashAndBuf()
 | 
			
		||||
	defer putHashAndBuf(hb)
 | 
			
		||||
 | 
			
		||||
	sum := hashNew()
 | 
			
		||||
	for _, labelName := range labelNames {
 | 
			
		||||
		hb.b.WriteString(labelName)
 | 
			
		||||
		hb.b.WriteByte(SeparatorByte)
 | 
			
		||||
		hb.b.WriteString(labels[labelName])
 | 
			
		||||
		hb.b.WriteByte(SeparatorByte)
 | 
			
		||||
		hb.h.Write(hb.b.Bytes())
 | 
			
		||||
		hb.b.Reset()
 | 
			
		||||
		sum = hashAdd(sum, labelName)
 | 
			
		||||
		sum = hashAddByte(sum, SeparatorByte)
 | 
			
		||||
		sum = hashAdd(sum, labels[labelName])
 | 
			
		||||
		sum = hashAddByte(sum, SeparatorByte)
 | 
			
		||||
	}
 | 
			
		||||
	return hb.h.Sum64()
 | 
			
		||||
	return sum
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as
 | 
			
		||||
@@ -93,18 +64,14 @@ func labelSetToFingerprint(ls LabelSet) Fingerprint {
 | 
			
		||||
	}
 | 
			
		||||
	sort.Sort(labelNames)
 | 
			
		||||
 | 
			
		||||
	hb := getHashAndBuf()
 | 
			
		||||
	defer putHashAndBuf(hb)
 | 
			
		||||
 | 
			
		||||
	sum := hashNew()
 | 
			
		||||
	for _, labelName := range labelNames {
 | 
			
		||||
		hb.b.WriteString(string(labelName))
 | 
			
		||||
		hb.b.WriteByte(SeparatorByte)
 | 
			
		||||
		hb.b.WriteString(string(ls[labelName]))
 | 
			
		||||
		hb.b.WriteByte(SeparatorByte)
 | 
			
		||||
		hb.h.Write(hb.b.Bytes())
 | 
			
		||||
		hb.b.Reset()
 | 
			
		||||
		sum = hashAdd(sum, string(labelName))
 | 
			
		||||
		sum = hashAddByte(sum, SeparatorByte)
 | 
			
		||||
		sum = hashAdd(sum, string(ls[labelName]))
 | 
			
		||||
		sum = hashAddByte(sum, SeparatorByte)
 | 
			
		||||
	}
 | 
			
		||||
	return Fingerprint(hb.h.Sum64())
 | 
			
		||||
	return Fingerprint(sum)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// labelSetToFastFingerprint works similar to labelSetToFingerprint but uses a
 | 
			
		||||
@@ -116,17 +83,12 @@ func labelSetToFastFingerprint(ls LabelSet) Fingerprint {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var result uint64
 | 
			
		||||
	hb := getHashAndBuf()
 | 
			
		||||
	defer putHashAndBuf(hb)
 | 
			
		||||
 | 
			
		||||
	for labelName, labelValue := range ls {
 | 
			
		||||
		hb.b.WriteString(string(labelName))
 | 
			
		||||
		hb.b.WriteByte(SeparatorByte)
 | 
			
		||||
		hb.b.WriteString(string(labelValue))
 | 
			
		||||
		hb.h.Write(hb.b.Bytes())
 | 
			
		||||
		result ^= hb.h.Sum64()
 | 
			
		||||
		hb.h.Reset()
 | 
			
		||||
		hb.b.Reset()
 | 
			
		||||
		sum := hashNew()
 | 
			
		||||
		sum = hashAdd(sum, string(labelName))
 | 
			
		||||
		sum = hashAddByte(sum, SeparatorByte)
 | 
			
		||||
		sum = hashAdd(sum, string(labelValue))
 | 
			
		||||
		result ^= sum
 | 
			
		||||
	}
 | 
			
		||||
	return Fingerprint(result)
 | 
			
		||||
}
 | 
			
		||||
@@ -136,24 +98,20 @@ func labelSetToFastFingerprint(ls LabelSet) Fingerprint {
 | 
			
		||||
// specified LabelNames into the signature calculation. The labels passed in
 | 
			
		||||
// will be sorted by this function.
 | 
			
		||||
func SignatureForLabels(m Metric, labels ...LabelName) uint64 {
 | 
			
		||||
	if len(m) == 0 || len(labels) == 0 {
 | 
			
		||||
	if len(labels) == 0 {
 | 
			
		||||
		return emptyLabelSignature
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sort.Sort(LabelNames(labels))
 | 
			
		||||
 | 
			
		||||
	hb := getHashAndBuf()
 | 
			
		||||
	defer putHashAndBuf(hb)
 | 
			
		||||
 | 
			
		||||
	sum := hashNew()
 | 
			
		||||
	for _, label := range labels {
 | 
			
		||||
		hb.b.WriteString(string(label))
 | 
			
		||||
		hb.b.WriteByte(SeparatorByte)
 | 
			
		||||
		hb.b.WriteString(string(m[label]))
 | 
			
		||||
		hb.b.WriteByte(SeparatorByte)
 | 
			
		||||
		hb.h.Write(hb.b.Bytes())
 | 
			
		||||
		hb.b.Reset()
 | 
			
		||||
		sum = hashAdd(sum, string(label))
 | 
			
		||||
		sum = hashAddByte(sum, SeparatorByte)
 | 
			
		||||
		sum = hashAdd(sum, string(m[label]))
 | 
			
		||||
		sum = hashAddByte(sum, SeparatorByte)
 | 
			
		||||
	}
 | 
			
		||||
	return hb.h.Sum64()
 | 
			
		||||
	return sum
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SignatureWithoutLabels works like LabelsToSignature but takes a Metric as
 | 
			
		||||
@@ -175,16 +133,12 @@ func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 {
 | 
			
		||||
	}
 | 
			
		||||
	sort.Sort(labelNames)
 | 
			
		||||
 | 
			
		||||
	hb := getHashAndBuf()
 | 
			
		||||
	defer putHashAndBuf(hb)
 | 
			
		||||
 | 
			
		||||
	sum := hashNew()
 | 
			
		||||
	for _, labelName := range labelNames {
 | 
			
		||||
		hb.b.WriteString(string(labelName))
 | 
			
		||||
		hb.b.WriteByte(SeparatorByte)
 | 
			
		||||
		hb.b.WriteString(string(m[labelName]))
 | 
			
		||||
		hb.b.WriteByte(SeparatorByte)
 | 
			
		||||
		hb.h.Write(hb.b.Bytes())
 | 
			
		||||
		hb.b.Reset()
 | 
			
		||||
		sum = hashAdd(sum, string(labelName))
 | 
			
		||||
		sum = hashAddByte(sum, SeparatorByte)
 | 
			
		||||
		sum = hashAdd(sum, string(m[labelName]))
 | 
			
		||||
		sum = hashAddByte(sum, SeparatorByte)
 | 
			
		||||
	}
 | 
			
		||||
	return hb.h.Sum64()
 | 
			
		||||
	return sum
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										46
									
								
								vendor/github.com/prometheus/common/model/silence.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/prometheus/common/model/silence.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -44,6 +44,21 @@ func (m *Matcher) UnmarshalJSON(b []byte) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate returns true iff all fields of the matcher have valid values.
 | 
			
		||||
func (m *Matcher) Validate() error {
 | 
			
		||||
	if !m.Name.IsValid() {
 | 
			
		||||
		return fmt.Errorf("invalid name %q", m.Name)
 | 
			
		||||
	}
 | 
			
		||||
	if m.IsRegex {
 | 
			
		||||
		if _, err := regexp.Compile(m.Value); err != nil {
 | 
			
		||||
			return fmt.Errorf("invalid regular expression %q", m.Value)
 | 
			
		||||
		}
 | 
			
		||||
	} else if !LabelValue(m.Value).IsValid() || len(m.Value) == 0 {
 | 
			
		||||
		return fmt.Errorf("invalid value %q", m.Value)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Silence defines the representation of a silence definiton
 | 
			
		||||
// in the Prometheus eco-system.
 | 
			
		||||
type Silence struct {
 | 
			
		||||
@@ -58,3 +73,34 @@ type Silence struct {
 | 
			
		||||
	CreatedBy string    `json:"createdBy"`
 | 
			
		||||
	Comment   string    `json:"comment,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate returns true iff all fields of the silence have valid values.
 | 
			
		||||
func (s *Silence) Validate() error {
 | 
			
		||||
	if len(s.Matchers) == 0 {
 | 
			
		||||
		return fmt.Errorf("at least one matcher required")
 | 
			
		||||
	}
 | 
			
		||||
	for _, m := range s.Matchers {
 | 
			
		||||
		if err := m.Validate(); err != nil {
 | 
			
		||||
			return fmt.Errorf("invalid matcher: %s", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if s.StartsAt.IsZero() {
 | 
			
		||||
		return fmt.Errorf("start time missing")
 | 
			
		||||
	}
 | 
			
		||||
	if s.EndsAt.IsZero() {
 | 
			
		||||
		return fmt.Errorf("end time missing")
 | 
			
		||||
	}
 | 
			
		||||
	if s.EndsAt.Before(s.StartsAt) {
 | 
			
		||||
		return fmt.Errorf("start time must be before end time")
 | 
			
		||||
	}
 | 
			
		||||
	if s.CreatedBy == "" {
 | 
			
		||||
		return fmt.Errorf("creator information missing")
 | 
			
		||||
	}
 | 
			
		||||
	if s.Comment == "" {
 | 
			
		||||
		return fmt.Errorf("comment missing")
 | 
			
		||||
	}
 | 
			
		||||
	if s.CreatedAt.IsZero() {
 | 
			
		||||
		return fmt.Errorf("creation timestamp missing")
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										61
									
								
								vendor/github.com/prometheus/common/model/time.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/prometheus/common/model/time.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -163,51 +163,70 @@ func (t *Time) UnmarshalJSON(b []byte) error {
 | 
			
		||||
// This type should not propagate beyond the scope of input/output processing.
 | 
			
		||||
type Duration time.Duration
 | 
			
		||||
 | 
			
		||||
var durationRE = regexp.MustCompile("^([0-9]+)(y|w|d|h|m|s|ms)$")
 | 
			
		||||
 | 
			
		||||
// StringToDuration parses a string into a time.Duration, assuming that a year
 | 
			
		||||
// a day always has 24h.
 | 
			
		||||
// always has 365d, a week always has 7d, and a day always has 24h.
 | 
			
		||||
func ParseDuration(durationStr string) (Duration, error) {
 | 
			
		||||
	matches := durationRE.FindStringSubmatch(durationStr)
 | 
			
		||||
	if len(matches) != 3 {
 | 
			
		||||
		return 0, fmt.Errorf("not a valid duration string: %q", durationStr)
 | 
			
		||||
	}
 | 
			
		||||
	durSeconds, _ := strconv.Atoi(matches[1])
 | 
			
		||||
	dur := time.Duration(durSeconds) * time.Second
 | 
			
		||||
	unit := matches[2]
 | 
			
		||||
	switch unit {
 | 
			
		||||
	var (
 | 
			
		||||
		n, _ = strconv.Atoi(matches[1])
 | 
			
		||||
		dur  = time.Duration(n) * time.Millisecond
 | 
			
		||||
	)
 | 
			
		||||
	switch unit := matches[2]; unit {
 | 
			
		||||
	case "y":
 | 
			
		||||
		dur *= 1000 * 60 * 60 * 24 * 365
 | 
			
		||||
	case "w":
 | 
			
		||||
		dur *= 1000 * 60 * 60 * 24 * 7
 | 
			
		||||
	case "d":
 | 
			
		||||
		dur *= 60 * 60 * 24
 | 
			
		||||
		dur *= 1000 * 60 * 60 * 24
 | 
			
		||||
	case "h":
 | 
			
		||||
		dur *= 60 * 60
 | 
			
		||||
		dur *= 1000 * 60 * 60
 | 
			
		||||
	case "m":
 | 
			
		||||
		dur *= 60
 | 
			
		||||
		dur *= 1000 * 60
 | 
			
		||||
	case "s":
 | 
			
		||||
		dur *= 1
 | 
			
		||||
		dur *= 1000
 | 
			
		||||
	case "ms":
 | 
			
		||||
		// Value already correct
 | 
			
		||||
	default:
 | 
			
		||||
		return 0, fmt.Errorf("invalid time unit in duration string: %q", unit)
 | 
			
		||||
	}
 | 
			
		||||
	return Duration(dur), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var durationRE = regexp.MustCompile("^([0-9]+)([ywdhms]+)$")
 | 
			
		||||
 | 
			
		||||
func (d Duration) String() string {
 | 
			
		||||
	seconds := int64(time.Duration(d) / time.Second)
 | 
			
		||||
	var (
 | 
			
		||||
		ms   = int64(time.Duration(d) / time.Millisecond)
 | 
			
		||||
		unit = "ms"
 | 
			
		||||
	)
 | 
			
		||||
	factors := map[string]int64{
 | 
			
		||||
		"d": 60 * 60 * 24,
 | 
			
		||||
		"h": 60 * 60,
 | 
			
		||||
		"m": 60,
 | 
			
		||||
		"s": 1,
 | 
			
		||||
		"y":  1000 * 60 * 60 * 24 * 365,
 | 
			
		||||
		"w":  1000 * 60 * 60 * 24 * 7,
 | 
			
		||||
		"d":  1000 * 60 * 60 * 24,
 | 
			
		||||
		"h":  1000 * 60 * 60,
 | 
			
		||||
		"m":  1000 * 60,
 | 
			
		||||
		"s":  1000,
 | 
			
		||||
		"ms": 1,
 | 
			
		||||
	}
 | 
			
		||||
	unit := "s"
 | 
			
		||||
 | 
			
		||||
	switch int64(0) {
 | 
			
		||||
	case seconds % factors["d"]:
 | 
			
		||||
	case ms % factors["y"]:
 | 
			
		||||
		unit = "y"
 | 
			
		||||
	case ms % factors["w"]:
 | 
			
		||||
		unit = "w"
 | 
			
		||||
	case ms % factors["d"]:
 | 
			
		||||
		unit = "d"
 | 
			
		||||
	case seconds % factors["h"]:
 | 
			
		||||
	case ms % factors["h"]:
 | 
			
		||||
		unit = "h"
 | 
			
		||||
	case seconds % factors["m"]:
 | 
			
		||||
	case ms % factors["m"]:
 | 
			
		||||
		unit = "m"
 | 
			
		||||
	case ms % factors["s"]:
 | 
			
		||||
		unit = "s"
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("%v%v", seconds/factors[unit], unit)
 | 
			
		||||
	return fmt.Sprintf("%v%v", ms/factors[unit], unit)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MarshalYAML implements the yaml.Marshaler interface.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								vendor/github.com/prometheus/common/model/value.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/prometheus/common/model/value.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -16,11 +16,28 @@ package model
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"math"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// ZeroSamplePair is the pseudo zero-value of SamplePair used to signal a
 | 
			
		||||
	// non-existing sample pair. It is a SamplePair with timestamp Earliest and
 | 
			
		||||
	// value 0.0. Note that the natural zero value of SamplePair has a timestamp
 | 
			
		||||
	// of 0, which is possible to appear in a real SamplePair and thus not
 | 
			
		||||
	// suitable to signal a non-existing SamplePair.
 | 
			
		||||
	ZeroSamplePair = SamplePair{Timestamp: Earliest}
 | 
			
		||||
 | 
			
		||||
	// ZeroSample is the pseudo zero-value of Sample used to signal a
 | 
			
		||||
	// non-existing sample. It is a Sample with timestamp Earliest, value 0.0,
 | 
			
		||||
	// and metric nil. Note that the natural zero value of Sample has a timestamp
 | 
			
		||||
	// of 0, which is possible to appear in a real Sample and thus not suitable
 | 
			
		||||
	// to signal a non-existing Sample.
 | 
			
		||||
	ZeroSample = Sample{Timestamp: Earliest}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A SampleValue is a representation of a value for a given sample at a given
 | 
			
		||||
// time.
 | 
			
		||||
type SampleValue float64
 | 
			
		||||
@@ -43,8 +60,14 @@ func (v *SampleValue) UnmarshalJSON(b []byte) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equal returns true if the value of v and o is equal or if both are NaN. Note
 | 
			
		||||
// that v==o is false if both are NaN. If you want the conventional float
 | 
			
		||||
// behavior, use == to compare two SampleValues.
 | 
			
		||||
func (v SampleValue) Equal(o SampleValue) bool {
 | 
			
		||||
	return v == o
 | 
			
		||||
	if v == o {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return math.IsNaN(float64(v)) && math.IsNaN(float64(o))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v SampleValue) String() string {
 | 
			
		||||
@@ -77,9 +100,9 @@ func (s *SamplePair) UnmarshalJSON(b []byte) error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equal returns true if this SamplePair and o have equal Values and equal
 | 
			
		||||
// Timestamps.
 | 
			
		||||
// Timestamps. The sematics of Value equality is defined by SampleValue.Equal.
 | 
			
		||||
func (s *SamplePair) Equal(o *SamplePair) bool {
 | 
			
		||||
	return s == o || (s.Value == o.Value && s.Timestamp.Equal(o.Timestamp))
 | 
			
		||||
	return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s SamplePair) String() string {
 | 
			
		||||
@@ -93,7 +116,8 @@ type Sample struct {
 | 
			
		||||
	Timestamp Time        `json:"timestamp"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equal compares first the metrics, then the timestamp, then the value.
 | 
			
		||||
// Equal compares first the metrics, then the timestamp, then the value. The
 | 
			
		||||
// sematics of value equality is defined by SampleValue.Equal.
 | 
			
		||||
func (s *Sample) Equal(o *Sample) bool {
 | 
			
		||||
	if s == o {
 | 
			
		||||
		return true
 | 
			
		||||
@@ -105,11 +129,8 @@ func (s *Sample) Equal(o *Sample) bool {
 | 
			
		||||
	if !s.Timestamp.Equal(o.Timestamp) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if s.Value != o.Value {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true
 | 
			
		||||
	return s.Value.Equal(o.Value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s Sample) String() string {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								vendor/github.com/prometheus/procfs/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/prometheus/procfs/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,7 +1,5 @@
 | 
			
		||||
sudo: false
 | 
			
		||||
language: go
 | 
			
		||||
go:
 | 
			
		||||
    - 1.3
 | 
			
		||||
    - 1.4
 | 
			
		||||
    - 1.5
 | 
			
		||||
    - tip
 | 
			
		||||
    - 1.6.4
 | 
			
		||||
    - 1.7.4
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/github.com/prometheus/procfs/AUTHORS.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/prometheus/procfs/AUTHORS.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,20 +0,0 @@
 | 
			
		||||
The Prometheus project was started by Matt T. Proud (emeritus) and
 | 
			
		||||
Julius Volz in 2012.
 | 
			
		||||
 | 
			
		||||
Maintainers of this repository:
 | 
			
		||||
 | 
			
		||||
* Tobias Schmidt <ts@soundcloud.com>
 | 
			
		||||
 | 
			
		||||
The following individuals have contributed code to this repository
 | 
			
		||||
(listed in alphabetical order):
 | 
			
		||||
 | 
			
		||||
* Armen Baghumian <abaghumian@noggin.com.au>
 | 
			
		||||
* Bjoern Rabenstein <beorn@soundcloud.com>
 | 
			
		||||
* David Cournapeau <cournape@gmail.com>
 | 
			
		||||
* Ji-Hoon, Seol <jihoon.seol@gmail.com>
 | 
			
		||||
* Jonas Große Sundrup <cherti@letopolis.de>
 | 
			
		||||
* Julius Volz <julius@soundcloud.com>
 | 
			
		||||
* Matthias Rampke <mr@soundcloud.com>
 | 
			
		||||
* Nicky Gerritsen <nicky@streamone.nl>
 | 
			
		||||
* Rémi Audebert <contact@halfr.net>
 | 
			
		||||
* Tobias Schmidt <tobidt@gmail.com>
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/github.com/prometheus/procfs/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/prometheus/procfs/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -10,17 +10,21 @@ load(
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "buddyinfo.go",
 | 
			
		||||
        "doc.go",
 | 
			
		||||
        "fs.go",
 | 
			
		||||
        "ipvs.go",
 | 
			
		||||
        "mdstat.go",
 | 
			
		||||
        "mountstats.go",
 | 
			
		||||
        "proc.go",
 | 
			
		||||
        "proc_io.go",
 | 
			
		||||
        "proc_limits.go",
 | 
			
		||||
        "proc_stat.go",
 | 
			
		||||
        "stat.go",
 | 
			
		||||
        "xfrm.go",
 | 
			
		||||
    ],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    deps = ["//vendor/github.com/prometheus/procfs/xfs:go_default_library"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
@@ -32,6 +36,9 @@ filegroup(
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
    name = "all-srcs",
 | 
			
		||||
    srcs = [":package-srcs"],
 | 
			
		||||
    srcs = [
 | 
			
		||||
        ":package-srcs",
 | 
			
		||||
        "//vendor/github.com/prometheus/procfs/xfs:all-srcs",
 | 
			
		||||
    ],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								vendor/github.com/prometheus/procfs/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/prometheus/procfs/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2,9 +2,9 @@
 | 
			
		||||
 | 
			
		||||
Prometheus uses GitHub to manage reviews of pull requests.
 | 
			
		||||
 | 
			
		||||
* If you have a trivial fix or improvement, go ahead and create a pull
 | 
			
		||||
  request, addressing (with `@...`) one or more of the maintainers
 | 
			
		||||
  (see [AUTHORS.md](AUTHORS.md)) in the description of the pull request.
 | 
			
		||||
* If you have a trivial fix or improvement, go ahead and create a pull request,
 | 
			
		||||
  addressing (with `@...`) the maintainer of this repository (see
 | 
			
		||||
  [MAINTAINERS.md](MAINTAINERS.md)) in the description of the pull request.
 | 
			
		||||
 | 
			
		||||
* If you plan to do something more involved, first discuss your ideas
 | 
			
		||||
  on our [mailing list](https://groups.google.com/forum/?fromgroups#!forum/prometheus-developers).
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/prometheus/procfs/MAINTAINERS.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/prometheus/procfs/MAINTAINERS.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
* Tobias Schmidt <tobidt@gmail.com>
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/github.com/prometheus/procfs/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/prometheus/procfs/Makefile
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
ci:
 | 
			
		||||
	go fmt
 | 
			
		||||
	! gofmt -l *.go | read nothing
 | 
			
		||||
	go vet
 | 
			
		||||
	go test -v ./...
 | 
			
		||||
	go get github.com/golang/lint/golint
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/prometheus/procfs/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/prometheus/procfs/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -8,3 +8,4 @@ backwards-incompatible ways without warnings. Use it at your own risk.
 | 
			
		||||
 | 
			
		||||
[](https://godoc.org/github.com/prometheus/procfs)
 | 
			
		||||
[](https://travis-ci.org/prometheus/procfs)
 | 
			
		||||
[](https://goreportcard.com/report/github.com/prometheus/procfs)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										95
									
								
								vendor/github.com/prometheus/procfs/buddyinfo.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								vendor/github.com/prometheus/procfs/buddyinfo.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
// Copyright 2017 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package procfs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A BuddyInfo is the details parsed from /proc/buddyinfo.
 | 
			
		||||
// The data is comprised of an array of free fragments of each size.
 | 
			
		||||
// The sizes are 2^n*PAGE_SIZE, where n is the array index.
 | 
			
		||||
type BuddyInfo struct {
 | 
			
		||||
	Node  string
 | 
			
		||||
	Zone  string
 | 
			
		||||
	Sizes []float64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewBuddyInfo reads the buddyinfo statistics.
 | 
			
		||||
func NewBuddyInfo() ([]BuddyInfo, error) {
 | 
			
		||||
	fs, err := NewFS(DefaultMountPoint)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return fs.NewBuddyInfo()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewBuddyInfo reads the buddyinfo statistics from the specified `proc` filesystem.
 | 
			
		||||
func (fs FS) NewBuddyInfo() ([]BuddyInfo, error) {
 | 
			
		||||
	file, err := os.Open(fs.Path("buddyinfo"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer file.Close()
 | 
			
		||||
 | 
			
		||||
	return parseBuddyInfo(file)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseBuddyInfo(r io.Reader) ([]BuddyInfo, error) {
 | 
			
		||||
	var (
 | 
			
		||||
		buddyInfo   = []BuddyInfo{}
 | 
			
		||||
		scanner     = bufio.NewScanner(r)
 | 
			
		||||
		bucketCount = -1
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	for scanner.Scan() {
 | 
			
		||||
		var err error
 | 
			
		||||
		line := scanner.Text()
 | 
			
		||||
		parts := strings.Fields(string(line))
 | 
			
		||||
 | 
			
		||||
		if len(parts) < 4 {
 | 
			
		||||
			return nil, fmt.Errorf("invalid number of fields when parsing buddyinfo")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		node := strings.TrimRight(parts[1], ",")
 | 
			
		||||
		zone := strings.TrimRight(parts[3], ",")
 | 
			
		||||
		arraySize := len(parts[4:])
 | 
			
		||||
 | 
			
		||||
		if bucketCount == -1 {
 | 
			
		||||
			bucketCount = arraySize
 | 
			
		||||
		} else {
 | 
			
		||||
			if bucketCount != arraySize {
 | 
			
		||||
				return nil, fmt.Errorf("mismatch in number of buddyinfo buckets, previous count %d, new count %d", bucketCount, arraySize)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sizes := make([]float64, arraySize)
 | 
			
		||||
		for i := 0; i < arraySize; i++ {
 | 
			
		||||
			sizes[i], err = strconv.ParseFloat(parts[i+4], 64)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, fmt.Errorf("invalid value in buddyinfo: %s", err)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		buddyInfo = append(buddyInfo, BuddyInfo{node, zone, sizes})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return buddyInfo, scanner.Err()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/github.com/prometheus/procfs/fs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								vendor/github.com/prometheus/procfs/fs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -4,6 +4,8 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
 | 
			
		||||
	"github.com/prometheus/procfs/xfs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// FS represents the pseudo-filesystem proc, which provides an interface to
 | 
			
		||||
@@ -27,14 +29,18 @@ func NewFS(mountPoint string) (FS, error) {
 | 
			
		||||
	return FS(mountPoint), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs FS) stat(p string) (os.FileInfo, error) {
 | 
			
		||||
	return os.Stat(path.Join(string(fs), p))
 | 
			
		||||
// Path returns the path of the given subsystem relative to the procfs root.
 | 
			
		||||
func (fs FS) Path(p ...string) string {
 | 
			
		||||
	return path.Join(append([]string{string(fs)}, p...)...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs FS) open(p string) (*os.File, error) {
 | 
			
		||||
	return os.Open(path.Join(string(fs), p))
 | 
			
		||||
}
 | 
			
		||||
// XFSStats retrieves XFS filesystem runtime statistics.
 | 
			
		||||
func (fs FS) XFSStats() (*xfs.Stats, error) {
 | 
			
		||||
	f, err := os.Open(fs.Path("fs/xfs/stat"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer f.Close()
 | 
			
		||||
 | 
			
		||||
func (fs FS) readlink(p string) (string, error) {
 | 
			
		||||
	return os.Readlink(path.Join(string(fs), p))
 | 
			
		||||
	return xfs.ParseStats(f)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										51
									
								
								vendor/github.com/prometheus/procfs/ipvs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										51
									
								
								vendor/github.com/prometheus/procfs/ipvs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -8,6 +8,7 @@ import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
@@ -32,6 +33,8 @@ type IPVSBackendStatus struct {
 | 
			
		||||
	LocalAddress net.IP
 | 
			
		||||
	// The local (virtual) port.
 | 
			
		||||
	LocalPort uint16
 | 
			
		||||
	// The local firewall mark
 | 
			
		||||
	LocalMark string
 | 
			
		||||
	// The transport protocol (TCP, UDP).
 | 
			
		||||
	Proto string
 | 
			
		||||
	// The remote (real) IP address.
 | 
			
		||||
@@ -58,7 +61,7 @@ func NewIPVSStats() (IPVSStats, error) {
 | 
			
		||||
 | 
			
		||||
// NewIPVSStats reads the IPVS statistics from the specified `proc` filesystem.
 | 
			
		||||
func (fs FS) NewIPVSStats() (IPVSStats, error) {
 | 
			
		||||
	file, err := fs.open("net/ip_vs_stats")
 | 
			
		||||
	file, err := os.Open(fs.Path("net/ip_vs_stats"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return IPVSStats{}, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -127,7 +130,7 @@ func NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
 | 
			
		||||
 | 
			
		||||
// NewIPVSBackendStatus reads and returns the status of all (virtual,real) server pairs from the specified `proc` filesystem.
 | 
			
		||||
func (fs FS) NewIPVSBackendStatus() ([]IPVSBackendStatus, error) {
 | 
			
		||||
	file, err := fs.open("net/ip_vs")
 | 
			
		||||
	file, err := os.Open(fs.Path("net/ip_vs"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -141,6 +144,7 @@ func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {
 | 
			
		||||
		status       []IPVSBackendStatus
 | 
			
		||||
		scanner      = bufio.NewScanner(file)
 | 
			
		||||
		proto        string
 | 
			
		||||
		localMark    string
 | 
			
		||||
		localAddress net.IP
 | 
			
		||||
		localPort    uint16
 | 
			
		||||
		err          error
 | 
			
		||||
@@ -159,10 +163,19 @@ func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			proto = fields[0]
 | 
			
		||||
			localMark = ""
 | 
			
		||||
			localAddress, localPort, err = parseIPPort(fields[1])
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
		case fields[0] == "FWM":
 | 
			
		||||
			if len(fields) < 2 {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			proto = fields[0]
 | 
			
		||||
			localMark = fields[1]
 | 
			
		||||
			localAddress = nil
 | 
			
		||||
			localPort = 0
 | 
			
		||||
		case fields[0] == "->":
 | 
			
		||||
			if len(fields) < 6 {
 | 
			
		||||
				continue
 | 
			
		||||
@@ -186,6 +199,7 @@ func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {
 | 
			
		||||
			status = append(status, IPVSBackendStatus{
 | 
			
		||||
				LocalAddress:  localAddress,
 | 
			
		||||
				LocalPort:     localPort,
 | 
			
		||||
				LocalMark:     localMark,
 | 
			
		||||
				RemoteAddress: remoteAddress,
 | 
			
		||||
				RemotePort:    remotePort,
 | 
			
		||||
				Proto:         proto,
 | 
			
		||||
@@ -199,22 +213,31 @@ func parseIPVSBackendStatus(file io.Reader) ([]IPVSBackendStatus, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseIPPort(s string) (net.IP, uint16, error) {
 | 
			
		||||
	tmp := strings.SplitN(s, ":", 2)
 | 
			
		||||
	var (
 | 
			
		||||
		ip  net.IP
 | 
			
		||||
		err error
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	if len(tmp) != 2 {
 | 
			
		||||
		return nil, 0, fmt.Errorf("invalid IP:Port: %s", s)
 | 
			
		||||
	switch len(s) {
 | 
			
		||||
	case 13:
 | 
			
		||||
		ip, err = hex.DecodeString(s[0:8])
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, 0, err
 | 
			
		||||
		}
 | 
			
		||||
	case 46:
 | 
			
		||||
		ip = net.ParseIP(s[1:40])
 | 
			
		||||
		if ip == nil {
 | 
			
		||||
			return nil, 0, fmt.Errorf("invalid IPv6 address: %s", s[1:40])
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, 0, fmt.Errorf("unexpected IP:Port: %s", s)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(tmp[0]) != 8 && len(tmp[0]) != 32 {
 | 
			
		||||
		return nil, 0, fmt.Errorf("invalid IP: %s", tmp[0])
 | 
			
		||||
	portString := s[len(s)-4:]
 | 
			
		||||
	if len(portString) != 4 {
 | 
			
		||||
		return nil, 0, fmt.Errorf("unexpected port string format: %s", portString)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ip, err := hex.DecodeString(tmp[0])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	port, err := strconv.ParseUint(tmp[1], 16, 16)
 | 
			
		||||
	port, err := strconv.ParseUint(portString, 16, 16)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, 0, err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										88
									
								
								vendor/github.com/prometheus/procfs/mdstat.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										88
									
								
								vendor/github.com/prometheus/procfs/mdstat.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -3,7 +3,6 @@ package procfs
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"path"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
@@ -32,36 +31,22 @@ type MDStat struct {
 | 
			
		||||
 | 
			
		||||
// ParseMDStat parses an mdstat-file and returns a struct with the relevant infos.
 | 
			
		||||
func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
 | 
			
		||||
	mdStatusFilePath := path.Join(string(fs), "mdstat")
 | 
			
		||||
	mdStatusFilePath := fs.Path("mdstat")
 | 
			
		||||
	content, err := ioutil.ReadFile(mdStatusFilePath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return []MDStat{}, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mdStatusFile := string(content)
 | 
			
		||||
 | 
			
		||||
	lines := strings.Split(mdStatusFile, "\n")
 | 
			
		||||
	var currentMD string
 | 
			
		||||
 | 
			
		||||
	// Each md has at least the deviceline, statusline and one empty line afterwards
 | 
			
		||||
	// so we will have probably something of the order len(lines)/3 devices
 | 
			
		||||
	// so we use that for preallocation.
 | 
			
		||||
	estimateMDs := len(lines) / 3
 | 
			
		||||
	mdStates := make([]MDStat, 0, estimateMDs)
 | 
			
		||||
 | 
			
		||||
	mdStates := []MDStat{}
 | 
			
		||||
	lines := strings.Split(string(content), "\n")
 | 
			
		||||
	for i, l := range lines {
 | 
			
		||||
		if l == "" {
 | 
			
		||||
			// Skip entirely empty lines.
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if l[0] == ' ' {
 | 
			
		||||
			// Those lines are not the beginning of a md-section.
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if strings.HasPrefix(l, "Personalities") || strings.HasPrefix(l, "unused") {
 | 
			
		||||
			// We aren't interested in lines with general info.
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -69,32 +54,30 @@ func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
 | 
			
		||||
		if len(mainLine) < 3 {
 | 
			
		||||
			return mdStates, fmt.Errorf("error parsing mdline: %s", l)
 | 
			
		||||
		}
 | 
			
		||||
		currentMD = mainLine[0]      // name of md-device
 | 
			
		||||
		activityState := mainLine[2] // activity status of said md-device
 | 
			
		||||
		mdName := mainLine[0]
 | 
			
		||||
		activityState := mainLine[2]
 | 
			
		||||
 | 
			
		||||
		if len(lines) <= i+3 {
 | 
			
		||||
			return mdStates, fmt.Errorf("error parsing %s: entry for %s has fewer lines than expected", mdStatusFilePath, currentMD)
 | 
			
		||||
			return mdStates, fmt.Errorf(
 | 
			
		||||
				"error parsing %s: too few lines for md device %s",
 | 
			
		||||
				mdStatusFilePath,
 | 
			
		||||
				mdName,
 | 
			
		||||
			)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		active, total, size, err := evalStatusline(lines[i+1]) // parse statusline, always present
 | 
			
		||||
		active, total, size, err := evalStatusline(lines[i+1])
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return mdStates, fmt.Errorf("error parsing %s: %s", mdStatusFilePath, err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//
 | 
			
		||||
		// Now get the number of synced blocks.
 | 
			
		||||
		//
 | 
			
		||||
 | 
			
		||||
		// Get the line number of the syncing-line.
 | 
			
		||||
		var j int
 | 
			
		||||
		if strings.Contains(lines[i+2], "bitmap") { // then skip the bitmap line
 | 
			
		||||
		// j is the line number of the syncing-line.
 | 
			
		||||
		j := i + 2
 | 
			
		||||
		if strings.Contains(lines[i+2], "bitmap") { // skip bitmap line
 | 
			
		||||
			j = i + 3
 | 
			
		||||
		} else {
 | 
			
		||||
			j = i + 2
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If device is syncing at the moment, get the number of currently synced bytes,
 | 
			
		||||
		// otherwise that number equals the size of the device.
 | 
			
		||||
		// If device is syncing at the moment, get the number of currently
 | 
			
		||||
		// synced bytes, otherwise that number equals the size of the device.
 | 
			
		||||
		syncedBlocks := size
 | 
			
		||||
		if strings.Contains(lines[j], "recovery") || strings.Contains(lines[j], "resync") {
 | 
			
		||||
			syncedBlocks, err = evalBuildline(lines[j])
 | 
			
		||||
@@ -103,8 +86,14 @@ func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		mdStates = append(mdStates, MDStat{currentMD, activityState, active, total, size, syncedBlocks})
 | 
			
		||||
 | 
			
		||||
		mdStates = append(mdStates, MDStat{
 | 
			
		||||
			Name:          mdName,
 | 
			
		||||
			ActivityState: activityState,
 | 
			
		||||
			DisksActive:   active,
 | 
			
		||||
			DisksTotal:    total,
 | 
			
		||||
			BlocksTotal:   size,
 | 
			
		||||
			BlocksSynced:  syncedBlocks,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return mdStates, nil
 | 
			
		||||
@@ -112,47 +101,38 @@ func (fs FS) ParseMDStat() (mdstates []MDStat, err error) {
 | 
			
		||||
 | 
			
		||||
func evalStatusline(statusline string) (active, total, size int64, err error) {
 | 
			
		||||
	matches := statuslineRE.FindStringSubmatch(statusline)
 | 
			
		||||
 | 
			
		||||
	// +1 to make it more obvious that the whole string containing the info is also returned as matches[0].
 | 
			
		||||
	if len(matches) != 3+1 {
 | 
			
		||||
		return 0, 0, 0, fmt.Errorf("unexpected number matches found in statusline: %s", statusline)
 | 
			
		||||
	if len(matches) != 4 {
 | 
			
		||||
		return 0, 0, 0, fmt.Errorf("unexpected statusline: %s", statusline)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size, err = strconv.ParseInt(matches[1], 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline)
 | 
			
		||||
		return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	total, err = strconv.ParseInt(matches[2], 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline)
 | 
			
		||||
		return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	active, err = strconv.ParseInt(matches[3], 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, 0, 0, fmt.Errorf("%s in statusline: %s", err, statusline)
 | 
			
		||||
		return 0, 0, 0, fmt.Errorf("unexpected statusline %s: %s", statusline, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return active, total, size, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Gets the size that has already been synced out of the sync-line.
 | 
			
		||||
func evalBuildline(buildline string) (int64, error) {
 | 
			
		||||
func evalBuildline(buildline string) (syncedBlocks int64, err error) {
 | 
			
		||||
	matches := buildlineRE.FindStringSubmatch(buildline)
 | 
			
		||||
 | 
			
		||||
	// +1 to make it more obvious that the whole string containing the info is also returned as matches[0].
 | 
			
		||||
	if len(matches) < 1+1 {
 | 
			
		||||
		return 0, fmt.Errorf("too few matches found in buildline: %s", buildline)
 | 
			
		||||
	if len(matches) != 2 {
 | 
			
		||||
		return 0, fmt.Errorf("unexpected buildline: %s", buildline)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(matches) > 1+1 {
 | 
			
		||||
		return 0, fmt.Errorf("too many matches found in buildline: %s", buildline)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	syncedSize, err := strconv.ParseInt(matches[1], 10, 64)
 | 
			
		||||
	syncedBlocks, err = strconv.ParseInt(matches[1], 10, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, fmt.Errorf("%s in buildline: %s", err, buildline)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return syncedSize, nil
 | 
			
		||||
	return syncedBlocks, nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										556
									
								
								vendor/github.com/prometheus/procfs/mountstats.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										556
									
								
								vendor/github.com/prometheus/procfs/mountstats.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,556 @@
 | 
			
		||||
package procfs
 | 
			
		||||
 | 
			
		||||
// While implementing parsing of /proc/[pid]/mountstats, this blog was used
 | 
			
		||||
// heavily as a reference:
 | 
			
		||||
//   https://utcc.utoronto.ca/~cks/space/blog/linux/NFSMountstatsIndex
 | 
			
		||||
//
 | 
			
		||||
// Special thanks to Chris Siebenmann for all of his posts explaining the
 | 
			
		||||
// various statistics available for NFS.
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Constants shared between multiple functions.
 | 
			
		||||
const (
 | 
			
		||||
	deviceEntryLen = 8
 | 
			
		||||
 | 
			
		||||
	fieldBytesLen  = 8
 | 
			
		||||
	fieldEventsLen = 27
 | 
			
		||||
 | 
			
		||||
	statVersion10 = "1.0"
 | 
			
		||||
	statVersion11 = "1.1"
 | 
			
		||||
 | 
			
		||||
	fieldTransport10Len = 10
 | 
			
		||||
	fieldTransport11Len = 13
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A Mount is a device mount parsed from /proc/[pid]/mountstats.
 | 
			
		||||
type Mount struct {
 | 
			
		||||
	// Name of the device.
 | 
			
		||||
	Device string
 | 
			
		||||
	// The mount point of the device.
 | 
			
		||||
	Mount string
 | 
			
		||||
	// The filesystem type used by the device.
 | 
			
		||||
	Type string
 | 
			
		||||
	// If available additional statistics related to this Mount.
 | 
			
		||||
	// Use a type assertion to determine if additional statistics are available.
 | 
			
		||||
	Stats MountStats
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A MountStats is a type which contains detailed statistics for a specific
 | 
			
		||||
// type of Mount.
 | 
			
		||||
type MountStats interface {
 | 
			
		||||
	mountStats()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A MountStatsNFS is a MountStats implementation for NFSv3 and v4 mounts.
 | 
			
		||||
type MountStatsNFS struct {
 | 
			
		||||
	// The version of statistics provided.
 | 
			
		||||
	StatVersion string
 | 
			
		||||
	// The age of the NFS mount.
 | 
			
		||||
	Age time.Duration
 | 
			
		||||
	// Statistics related to byte counters for various operations.
 | 
			
		||||
	Bytes NFSBytesStats
 | 
			
		||||
	// Statistics related to various NFS event occurrences.
 | 
			
		||||
	Events NFSEventsStats
 | 
			
		||||
	// Statistics broken down by filesystem operation.
 | 
			
		||||
	Operations []NFSOperationStats
 | 
			
		||||
	// Statistics about the NFS RPC transport.
 | 
			
		||||
	Transport NFSTransportStats
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mountStats implements MountStats.
 | 
			
		||||
func (m MountStatsNFS) mountStats() {}
 | 
			
		||||
 | 
			
		||||
// A NFSBytesStats contains statistics about the number of bytes read and written
 | 
			
		||||
// by an NFS client to and from an NFS server.
 | 
			
		||||
type NFSBytesStats struct {
 | 
			
		||||
	// Number of bytes read using the read() syscall.
 | 
			
		||||
	Read uint64
 | 
			
		||||
	// Number of bytes written using the write() syscall.
 | 
			
		||||
	Write uint64
 | 
			
		||||
	// Number of bytes read using the read() syscall in O_DIRECT mode.
 | 
			
		||||
	DirectRead uint64
 | 
			
		||||
	// Number of bytes written using the write() syscall in O_DIRECT mode.
 | 
			
		||||
	DirectWrite uint64
 | 
			
		||||
	// Number of bytes read from the NFS server, in total.
 | 
			
		||||
	ReadTotal uint64
 | 
			
		||||
	// Number of bytes written to the NFS server, in total.
 | 
			
		||||
	WriteTotal uint64
 | 
			
		||||
	// Number of pages read directly via mmap()'d files.
 | 
			
		||||
	ReadPages uint64
 | 
			
		||||
	// Number of pages written directly via mmap()'d files.
 | 
			
		||||
	WritePages uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A NFSEventsStats contains statistics about NFS event occurrences.
 | 
			
		||||
type NFSEventsStats struct {
 | 
			
		||||
	// Number of times cached inode attributes are re-validated from the server.
 | 
			
		||||
	InodeRevalidate uint64
 | 
			
		||||
	// Number of times cached dentry nodes are re-validated from the server.
 | 
			
		||||
	DnodeRevalidate uint64
 | 
			
		||||
	// Number of times an inode cache is cleared.
 | 
			
		||||
	DataInvalidate uint64
 | 
			
		||||
	// Number of times cached inode attributes are invalidated.
 | 
			
		||||
	AttributeInvalidate uint64
 | 
			
		||||
	// Number of times files or directories have been open()'d.
 | 
			
		||||
	VFSOpen uint64
 | 
			
		||||
	// Number of times a directory lookup has occurred.
 | 
			
		||||
	VFSLookup uint64
 | 
			
		||||
	// Number of times permissions have been checked.
 | 
			
		||||
	VFSAccess uint64
 | 
			
		||||
	// Number of updates (and potential writes) to pages.
 | 
			
		||||
	VFSUpdatePage uint64
 | 
			
		||||
	// Number of pages read directly via mmap()'d files.
 | 
			
		||||
	VFSReadPage uint64
 | 
			
		||||
	// Number of times a group of pages have been read.
 | 
			
		||||
	VFSReadPages uint64
 | 
			
		||||
	// Number of pages written directly via mmap()'d files.
 | 
			
		||||
	VFSWritePage uint64
 | 
			
		||||
	// Number of times a group of pages have been written.
 | 
			
		||||
	VFSWritePages uint64
 | 
			
		||||
	// Number of times directory entries have been read with getdents().
 | 
			
		||||
	VFSGetdents uint64
 | 
			
		||||
	// Number of times attributes have been set on inodes.
 | 
			
		||||
	VFSSetattr uint64
 | 
			
		||||
	// Number of pending writes that have been forcefully flushed to the server.
 | 
			
		||||
	VFSFlush uint64
 | 
			
		||||
	// Number of times fsync() has been called on directories and files.
 | 
			
		||||
	VFSFsync uint64
 | 
			
		||||
	// Number of times locking has been attempted on a file.
 | 
			
		||||
	VFSLock uint64
 | 
			
		||||
	// Number of times files have been closed and released.
 | 
			
		||||
	VFSFileRelease uint64
 | 
			
		||||
	// Unknown.  Possibly unused.
 | 
			
		||||
	CongestionWait uint64
 | 
			
		||||
	// Number of times files have been truncated.
 | 
			
		||||
	Truncation uint64
 | 
			
		||||
	// Number of times a file has been grown due to writes beyond its existing end.
 | 
			
		||||
	WriteExtension uint64
 | 
			
		||||
	// Number of times a file was removed while still open by another process.
 | 
			
		||||
	SillyRename uint64
 | 
			
		||||
	// Number of times the NFS server gave less data than expected while reading.
 | 
			
		||||
	ShortRead uint64
 | 
			
		||||
	// Number of times the NFS server wrote less data than expected while writing.
 | 
			
		||||
	ShortWrite uint64
 | 
			
		||||
	// Number of times the NFS server indicated EJUKEBOX; retrieving data from
 | 
			
		||||
	// offline storage.
 | 
			
		||||
	JukeboxDelay uint64
 | 
			
		||||
	// Number of NFS v4.1+ pNFS reads.
 | 
			
		||||
	PNFSRead uint64
 | 
			
		||||
	// Number of NFS v4.1+ pNFS writes.
 | 
			
		||||
	PNFSWrite uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A NFSOperationStats contains statistics for a single operation.
 | 
			
		||||
type NFSOperationStats struct {
 | 
			
		||||
	// The name of the operation.
 | 
			
		||||
	Operation string
 | 
			
		||||
	// Number of requests performed for this operation.
 | 
			
		||||
	Requests uint64
 | 
			
		||||
	// Number of times an actual RPC request has been transmitted for this operation.
 | 
			
		||||
	Transmissions uint64
 | 
			
		||||
	// Number of times a request has had a major timeout.
 | 
			
		||||
	MajorTimeouts uint64
 | 
			
		||||
	// Number of bytes sent for this operation, including RPC headers and payload.
 | 
			
		||||
	BytesSent uint64
 | 
			
		||||
	// Number of bytes received for this operation, including RPC headers and payload.
 | 
			
		||||
	BytesReceived uint64
 | 
			
		||||
	// Duration all requests spent queued for transmission before they were sent.
 | 
			
		||||
	CumulativeQueueTime time.Duration
 | 
			
		||||
	// Duration it took to get a reply back after the request was transmitted.
 | 
			
		||||
	CumulativeTotalResponseTime time.Duration
 | 
			
		||||
	// Duration from when a request was enqueued to when it was completely handled.
 | 
			
		||||
	CumulativeTotalRequestTime time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A NFSTransportStats contains statistics for the NFS mount RPC requests and
 | 
			
		||||
// responses.
 | 
			
		||||
type NFSTransportStats struct {
 | 
			
		||||
	// The local port used for the NFS mount.
 | 
			
		||||
	Port uint64
 | 
			
		||||
	// Number of times the client has had to establish a connection from scratch
 | 
			
		||||
	// to the NFS server.
 | 
			
		||||
	Bind uint64
 | 
			
		||||
	// Number of times the client has made a TCP connection to the NFS server.
 | 
			
		||||
	Connect uint64
 | 
			
		||||
	// Duration (in jiffies, a kernel internal unit of time) the NFS mount has
 | 
			
		||||
	// spent waiting for connections to the server to be established.
 | 
			
		||||
	ConnectIdleTime uint64
 | 
			
		||||
	// Duration since the NFS mount last saw any RPC traffic.
 | 
			
		||||
	IdleTime time.Duration
 | 
			
		||||
	// Number of RPC requests for this mount sent to the NFS server.
 | 
			
		||||
	Sends uint64
 | 
			
		||||
	// Number of RPC responses for this mount received from the NFS server.
 | 
			
		||||
	Receives uint64
 | 
			
		||||
	// Number of times the NFS server sent a response with a transaction ID
 | 
			
		||||
	// unknown to this client.
 | 
			
		||||
	BadTransactionIDs uint64
 | 
			
		||||
	// A running counter, incremented on each request as the current difference
 | 
			
		||||
	// ebetween sends and receives.
 | 
			
		||||
	CumulativeActiveRequests uint64
 | 
			
		||||
	// A running counter, incremented on each request by the current backlog
 | 
			
		||||
	// queue size.
 | 
			
		||||
	CumulativeBacklog uint64
 | 
			
		||||
 | 
			
		||||
	// Stats below only available with stat version 1.1.
 | 
			
		||||
 | 
			
		||||
	// Maximum number of simultaneously active RPC requests ever used.
 | 
			
		||||
	MaximumRPCSlotsUsed uint64
 | 
			
		||||
	// A running counter, incremented on each request as the current size of the
 | 
			
		||||
	// sending queue.
 | 
			
		||||
	CumulativeSendingQueue uint64
 | 
			
		||||
	// A running counter, incremented on each request as the current size of the
 | 
			
		||||
	// pending queue.
 | 
			
		||||
	CumulativePendingQueue uint64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseMountStats parses a /proc/[pid]/mountstats file and returns a slice
 | 
			
		||||
// of Mount structures containing detailed information about each mount.
 | 
			
		||||
// If available, statistics for each mount are parsed as well.
 | 
			
		||||
func parseMountStats(r io.Reader) ([]*Mount, error) {
 | 
			
		||||
	const (
 | 
			
		||||
		device            = "device"
 | 
			
		||||
		statVersionPrefix = "statvers="
 | 
			
		||||
 | 
			
		||||
		nfs3Type = "nfs"
 | 
			
		||||
		nfs4Type = "nfs4"
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	var mounts []*Mount
 | 
			
		||||
 | 
			
		||||
	s := bufio.NewScanner(r)
 | 
			
		||||
	for s.Scan() {
 | 
			
		||||
		// Only look for device entries in this function
 | 
			
		||||
		ss := strings.Fields(string(s.Bytes()))
 | 
			
		||||
		if len(ss) == 0 || ss[0] != device {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		m, err := parseMount(ss)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Does this mount also possess statistics information?
 | 
			
		||||
		if len(ss) > deviceEntryLen {
 | 
			
		||||
			// Only NFSv3 and v4 are supported for parsing statistics
 | 
			
		||||
			if m.Type != nfs3Type && m.Type != nfs4Type {
 | 
			
		||||
				return nil, fmt.Errorf("cannot parse MountStats for fstype %q", m.Type)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			statVersion := strings.TrimPrefix(ss[8], statVersionPrefix)
 | 
			
		||||
 | 
			
		||||
			stats, err := parseMountStatsNFS(s, statVersion)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			m.Stats = stats
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		mounts = append(mounts, m)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return mounts, s.Err()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseMount parses an entry in /proc/[pid]/mountstats in the format:
 | 
			
		||||
//   device [device] mounted on [mount] with fstype [type]
 | 
			
		||||
func parseMount(ss []string) (*Mount, error) {
 | 
			
		||||
	if len(ss) < deviceEntryLen {
 | 
			
		||||
		return nil, fmt.Errorf("invalid device entry: %v", ss)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check for specific words appearing at specific indices to ensure
 | 
			
		||||
	// the format is consistent with what we expect
 | 
			
		||||
	format := []struct {
 | 
			
		||||
		i int
 | 
			
		||||
		s string
 | 
			
		||||
	}{
 | 
			
		||||
		{i: 0, s: "device"},
 | 
			
		||||
		{i: 2, s: "mounted"},
 | 
			
		||||
		{i: 3, s: "on"},
 | 
			
		||||
		{i: 5, s: "with"},
 | 
			
		||||
		{i: 6, s: "fstype"},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, f := range format {
 | 
			
		||||
		if ss[f.i] != f.s {
 | 
			
		||||
			return nil, fmt.Errorf("invalid device entry: %v", ss)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &Mount{
 | 
			
		||||
		Device: ss[1],
 | 
			
		||||
		Mount:  ss[4],
 | 
			
		||||
		Type:   ss[7],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseMountStatsNFS parses a MountStatsNFS by scanning additional information
 | 
			
		||||
// related to NFS statistics.
 | 
			
		||||
func parseMountStatsNFS(s *bufio.Scanner, statVersion string) (*MountStatsNFS, error) {
 | 
			
		||||
	// Field indicators for parsing specific types of data
 | 
			
		||||
	const (
 | 
			
		||||
		fieldAge        = "age:"
 | 
			
		||||
		fieldBytes      = "bytes:"
 | 
			
		||||
		fieldEvents     = "events:"
 | 
			
		||||
		fieldPerOpStats = "per-op"
 | 
			
		||||
		fieldTransport  = "xprt:"
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	stats := &MountStatsNFS{
 | 
			
		||||
		StatVersion: statVersion,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for s.Scan() {
 | 
			
		||||
		ss := strings.Fields(string(s.Bytes()))
 | 
			
		||||
		if len(ss) == 0 {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if len(ss) < 2 {
 | 
			
		||||
			return nil, fmt.Errorf("not enough information for NFS stats: %v", ss)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch ss[0] {
 | 
			
		||||
		case fieldAge:
 | 
			
		||||
			// Age integer is in seconds
 | 
			
		||||
			d, err := time.ParseDuration(ss[1] + "s")
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			stats.Age = d
 | 
			
		||||
		case fieldBytes:
 | 
			
		||||
			bstats, err := parseNFSBytesStats(ss[1:])
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			stats.Bytes = *bstats
 | 
			
		||||
		case fieldEvents:
 | 
			
		||||
			estats, err := parseNFSEventsStats(ss[1:])
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			stats.Events = *estats
 | 
			
		||||
		case fieldTransport:
 | 
			
		||||
			if len(ss) < 3 {
 | 
			
		||||
				return nil, fmt.Errorf("not enough information for NFS transport stats: %v", ss)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			tstats, err := parseNFSTransportStats(ss[2:], statVersion)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			stats.Transport = *tstats
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// When encountering "per-operation statistics", we must break this
 | 
			
		||||
		// loop and parse them separately to ensure we can terminate parsing
 | 
			
		||||
		// before reaching another device entry; hence why this 'if' statement
 | 
			
		||||
		// is not just another switch case
 | 
			
		||||
		if ss[0] == fieldPerOpStats {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := s.Err(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// NFS per-operation stats appear last before the next device entry
 | 
			
		||||
	perOpStats, err := parseNFSOperationStats(s)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stats.Operations = perOpStats
 | 
			
		||||
 | 
			
		||||
	return stats, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseNFSBytesStats parses a NFSBytesStats line using an input set of
 | 
			
		||||
// integer fields.
 | 
			
		||||
func parseNFSBytesStats(ss []string) (*NFSBytesStats, error) {
 | 
			
		||||
	if len(ss) != fieldBytesLen {
 | 
			
		||||
		return nil, fmt.Errorf("invalid NFS bytes stats: %v", ss)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ns := make([]uint64, 0, fieldBytesLen)
 | 
			
		||||
	for _, s := range ss {
 | 
			
		||||
		n, err := strconv.ParseUint(s, 10, 64)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ns = append(ns, n)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &NFSBytesStats{
 | 
			
		||||
		Read:        ns[0],
 | 
			
		||||
		Write:       ns[1],
 | 
			
		||||
		DirectRead:  ns[2],
 | 
			
		||||
		DirectWrite: ns[3],
 | 
			
		||||
		ReadTotal:   ns[4],
 | 
			
		||||
		WriteTotal:  ns[5],
 | 
			
		||||
		ReadPages:   ns[6],
 | 
			
		||||
		WritePages:  ns[7],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseNFSEventsStats parses a NFSEventsStats line using an input set of
 | 
			
		||||
// integer fields.
 | 
			
		||||
func parseNFSEventsStats(ss []string) (*NFSEventsStats, error) {
 | 
			
		||||
	if len(ss) != fieldEventsLen {
 | 
			
		||||
		return nil, fmt.Errorf("invalid NFS events stats: %v", ss)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ns := make([]uint64, 0, fieldEventsLen)
 | 
			
		||||
	for _, s := range ss {
 | 
			
		||||
		n, err := strconv.ParseUint(s, 10, 64)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ns = append(ns, n)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &NFSEventsStats{
 | 
			
		||||
		InodeRevalidate:     ns[0],
 | 
			
		||||
		DnodeRevalidate:     ns[1],
 | 
			
		||||
		DataInvalidate:      ns[2],
 | 
			
		||||
		AttributeInvalidate: ns[3],
 | 
			
		||||
		VFSOpen:             ns[4],
 | 
			
		||||
		VFSLookup:           ns[5],
 | 
			
		||||
		VFSAccess:           ns[6],
 | 
			
		||||
		VFSUpdatePage:       ns[7],
 | 
			
		||||
		VFSReadPage:         ns[8],
 | 
			
		||||
		VFSReadPages:        ns[9],
 | 
			
		||||
		VFSWritePage:        ns[10],
 | 
			
		||||
		VFSWritePages:       ns[11],
 | 
			
		||||
		VFSGetdents:         ns[12],
 | 
			
		||||
		VFSSetattr:          ns[13],
 | 
			
		||||
		VFSFlush:            ns[14],
 | 
			
		||||
		VFSFsync:            ns[15],
 | 
			
		||||
		VFSLock:             ns[16],
 | 
			
		||||
		VFSFileRelease:      ns[17],
 | 
			
		||||
		CongestionWait:      ns[18],
 | 
			
		||||
		Truncation:          ns[19],
 | 
			
		||||
		WriteExtension:      ns[20],
 | 
			
		||||
		SillyRename:         ns[21],
 | 
			
		||||
		ShortRead:           ns[22],
 | 
			
		||||
		ShortWrite:          ns[23],
 | 
			
		||||
		JukeboxDelay:        ns[24],
 | 
			
		||||
		PNFSRead:            ns[25],
 | 
			
		||||
		PNFSWrite:           ns[26],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseNFSOperationStats parses a slice of NFSOperationStats by scanning
 | 
			
		||||
// additional information about per-operation statistics until an empty
 | 
			
		||||
// line is reached.
 | 
			
		||||
func parseNFSOperationStats(s *bufio.Scanner) ([]NFSOperationStats, error) {
 | 
			
		||||
	const (
 | 
			
		||||
		// Number of expected fields in each per-operation statistics set
 | 
			
		||||
		numFields = 9
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	var ops []NFSOperationStats
 | 
			
		||||
 | 
			
		||||
	for s.Scan() {
 | 
			
		||||
		ss := strings.Fields(string(s.Bytes()))
 | 
			
		||||
		if len(ss) == 0 {
 | 
			
		||||
			// Must break when reading a blank line after per-operation stats to
 | 
			
		||||
			// enable top-level function to parse the next device entry
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(ss) != numFields {
 | 
			
		||||
			return nil, fmt.Errorf("invalid NFS per-operations stats: %v", ss)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Skip string operation name for integers
 | 
			
		||||
		ns := make([]uint64, 0, numFields-1)
 | 
			
		||||
		for _, st := range ss[1:] {
 | 
			
		||||
			n, err := strconv.ParseUint(st, 10, 64)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ns = append(ns, n)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ops = append(ops, NFSOperationStats{
 | 
			
		||||
			Operation:                   strings.TrimSuffix(ss[0], ":"),
 | 
			
		||||
			Requests:                    ns[0],
 | 
			
		||||
			Transmissions:               ns[1],
 | 
			
		||||
			MajorTimeouts:               ns[2],
 | 
			
		||||
			BytesSent:                   ns[3],
 | 
			
		||||
			BytesReceived:               ns[4],
 | 
			
		||||
			CumulativeQueueTime:         time.Duration(ns[5]) * time.Millisecond,
 | 
			
		||||
			CumulativeTotalResponseTime: time.Duration(ns[6]) * time.Millisecond,
 | 
			
		||||
			CumulativeTotalRequestTime:  time.Duration(ns[7]) * time.Millisecond,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ops, s.Err()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseNFSTransportStats parses a NFSTransportStats line using an input set of
 | 
			
		||||
// integer fields matched to a specific stats version.
 | 
			
		||||
func parseNFSTransportStats(ss []string, statVersion string) (*NFSTransportStats, error) {
 | 
			
		||||
	switch statVersion {
 | 
			
		||||
	case statVersion10:
 | 
			
		||||
		if len(ss) != fieldTransport10Len {
 | 
			
		||||
			return nil, fmt.Errorf("invalid NFS transport stats 1.0 statement: %v", ss)
 | 
			
		||||
		}
 | 
			
		||||
	case statVersion11:
 | 
			
		||||
		if len(ss) != fieldTransport11Len {
 | 
			
		||||
			return nil, fmt.Errorf("invalid NFS transport stats 1.1 statement: %v", ss)
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		return nil, fmt.Errorf("unrecognized NFS transport stats version: %q", statVersion)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Allocate enough for v1.1 stats since zero value for v1.1 stats will be okay
 | 
			
		||||
	// in a v1.0 response.
 | 
			
		||||
	//
 | 
			
		||||
	// Note: slice length must be set to length of v1.1 stats to avoid a panic when
 | 
			
		||||
	// only v1.0 stats are present.
 | 
			
		||||
	// See: https://github.com/prometheus/node_exporter/issues/571.
 | 
			
		||||
	ns := make([]uint64, fieldTransport11Len)
 | 
			
		||||
	for i, s := range ss {
 | 
			
		||||
		n, err := strconv.ParseUint(s, 10, 64)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ns[i] = n
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &NFSTransportStats{
 | 
			
		||||
		Port:                     ns[0],
 | 
			
		||||
		Bind:                     ns[1],
 | 
			
		||||
		Connect:                  ns[2],
 | 
			
		||||
		ConnectIdleTime:          ns[3],
 | 
			
		||||
		IdleTime:                 time.Duration(ns[4]) * time.Second,
 | 
			
		||||
		Sends:                    ns[5],
 | 
			
		||||
		Receives:                 ns[6],
 | 
			
		||||
		BadTransactionIDs:        ns[7],
 | 
			
		||||
		CumulativeActiveRequests: ns[8],
 | 
			
		||||
		CumulativeBacklog:        ns[9],
 | 
			
		||||
		MaximumRPCSlotsUsed:      ns[10],
 | 
			
		||||
		CumulativeSendingQueue:   ns[11],
 | 
			
		||||
		CumulativePendingQueue:   ns[12],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								vendor/github.com/prometheus/procfs/proc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								vendor/github.com/prometheus/procfs/proc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -4,7 +4,6 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
@@ -42,7 +41,7 @@ func NewProc(pid int) (Proc, error) {
 | 
			
		||||
	return fs.NewProc(pid)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AllProcs returns a list of all currently avaible processes under /proc.
 | 
			
		||||
// AllProcs returns a list of all currently available processes under /proc.
 | 
			
		||||
func AllProcs() (Procs, error) {
 | 
			
		||||
	fs, err := NewFS(DefaultMountPoint)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -53,7 +52,7 @@ func AllProcs() (Procs, error) {
 | 
			
		||||
 | 
			
		||||
// Self returns a process for the current process.
 | 
			
		||||
func (fs FS) Self() (Proc, error) {
 | 
			
		||||
	p, err := fs.readlink("self")
 | 
			
		||||
	p, err := os.Readlink(fs.Path("self"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return Proc{}, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -66,15 +65,15 @@ func (fs FS) Self() (Proc, error) {
 | 
			
		||||
 | 
			
		||||
// NewProc returns a process for the given pid.
 | 
			
		||||
func (fs FS) NewProc(pid int) (Proc, error) {
 | 
			
		||||
	if _, err := fs.stat(strconv.Itoa(pid)); err != nil {
 | 
			
		||||
	if _, err := os.Stat(fs.Path(strconv.Itoa(pid))); err != nil {
 | 
			
		||||
		return Proc{}, err
 | 
			
		||||
	}
 | 
			
		||||
	return Proc{PID: pid, fs: fs}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AllProcs returns a list of all currently avaible processes.
 | 
			
		||||
// AllProcs returns a list of all currently available processes.
 | 
			
		||||
func (fs FS) AllProcs() (Procs, error) {
 | 
			
		||||
	d, err := fs.open("")
 | 
			
		||||
	d, err := os.Open(fs.Path())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return Procs{}, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -99,7 +98,7 @@ func (fs FS) AllProcs() (Procs, error) {
 | 
			
		||||
 | 
			
		||||
// CmdLine returns the command line of a process.
 | 
			
		||||
func (p Proc) CmdLine() ([]string, error) {
 | 
			
		||||
	f, err := p.open("cmdline")
 | 
			
		||||
	f, err := os.Open(p.path("cmdline"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -117,10 +116,25 @@ func (p Proc) CmdLine() ([]string, error) {
 | 
			
		||||
	return strings.Split(string(data[:len(data)-1]), string(byte(0))), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Comm returns the command name of a process.
 | 
			
		||||
func (p Proc) Comm() (string, error) {
 | 
			
		||||
	f, err := os.Open(p.path("comm"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	defer f.Close()
 | 
			
		||||
 | 
			
		||||
	data, err := ioutil.ReadAll(f)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return strings.TrimSpace(string(data)), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Executable returns the absolute path of the executable command of a process.
 | 
			
		||||
func (p Proc) Executable() (string, error) {
 | 
			
		||||
	exe, err := p.readlink("exe")
 | 
			
		||||
 | 
			
		||||
	exe, err := os.Readlink(p.path("exe"))
 | 
			
		||||
	if os.IsNotExist(err) {
 | 
			
		||||
		return "", nil
 | 
			
		||||
	}
 | 
			
		||||
@@ -158,7 +172,7 @@ func (p Proc) FileDescriptorTargets() ([]string, error) {
 | 
			
		||||
	targets := make([]string, len(names))
 | 
			
		||||
 | 
			
		||||
	for i, name := range names {
 | 
			
		||||
		target, err := p.readlink("fd/" + name)
 | 
			
		||||
		target, err := os.Readlink(p.path("fd", name))
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			targets[i] = target
 | 
			
		||||
		}
 | 
			
		||||
@@ -178,8 +192,20 @@ func (p Proc) FileDescriptorsLen() (int, error) {
 | 
			
		||||
	return len(fds), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MountStats retrieves statistics and configuration for mount points in a
 | 
			
		||||
// process's namespace.
 | 
			
		||||
func (p Proc) MountStats() ([]*Mount, error) {
 | 
			
		||||
	f, err := os.Open(p.path("mountstats"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	defer f.Close()
 | 
			
		||||
 | 
			
		||||
	return parseMountStats(f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p Proc) fileDescriptors() ([]string, error) {
 | 
			
		||||
	d, err := p.open("fd")
 | 
			
		||||
	d, err := os.Open(p.path("fd"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -193,10 +219,6 @@ func (p Proc) fileDescriptors() ([]string, error) {
 | 
			
		||||
	return names, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p Proc) open(pa string) (*os.File, error) {
 | 
			
		||||
	return p.fs.open(path.Join(strconv.Itoa(p.PID), pa))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p Proc) readlink(pa string) (string, error) {
 | 
			
		||||
	return p.fs.readlink(path.Join(strconv.Itoa(p.PID), pa))
 | 
			
		||||
func (p Proc) path(pa ...string) string {
 | 
			
		||||
	return p.fs.Path(append([]string{strconv.Itoa(p.PID)}, pa...)...)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/github.com/prometheus/procfs/proc_io.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/prometheus/procfs/proc_io.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -3,6 +3,7 @@ package procfs
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ProcIO models the content of /proc/<pid>/io.
 | 
			
		||||
@@ -29,7 +30,7 @@ type ProcIO struct {
 | 
			
		||||
func (p Proc) NewIO() (ProcIO, error) {
 | 
			
		||||
	pio := ProcIO{}
 | 
			
		||||
 | 
			
		||||
	f, err := p.open("io")
 | 
			
		||||
	f, err := os.Open(p.path("io"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return pio, err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								vendor/github.com/prometheus/procfs/proc_limits.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/prometheus/procfs/proc_limits.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -3,29 +3,56 @@ package procfs
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ProcLimits represents the soft limits for each of the process's resource
 | 
			
		||||
// limits.
 | 
			
		||||
// limits. For more information see getrlimit(2):
 | 
			
		||||
// http://man7.org/linux/man-pages/man2/getrlimit.2.html.
 | 
			
		||||
type ProcLimits struct {
 | 
			
		||||
	CPUTime          int
 | 
			
		||||
	FileSize         int
 | 
			
		||||
	DataSize         int
 | 
			
		||||
	StackSize        int
 | 
			
		||||
	CoreFileSize     int
 | 
			
		||||
	ResidentSet      int
 | 
			
		||||
	Processes        int
 | 
			
		||||
	OpenFiles        int
 | 
			
		||||
	LockedMemory     int
 | 
			
		||||
	AddressSpace     int
 | 
			
		||||
	FileLocks        int
 | 
			
		||||
	PendingSignals   int
 | 
			
		||||
	MsqqueueSize     int
 | 
			
		||||
	NicePriority     int
 | 
			
		||||
	// CPU time limit in seconds.
 | 
			
		||||
	CPUTime int
 | 
			
		||||
	// Maximum size of files that the process may create.
 | 
			
		||||
	FileSize int
 | 
			
		||||
	// Maximum size of the process's data segment (initialized data,
 | 
			
		||||
	// uninitialized data, and heap).
 | 
			
		||||
	DataSize int
 | 
			
		||||
	// Maximum size of the process stack in bytes.
 | 
			
		||||
	StackSize int
 | 
			
		||||
	// Maximum size of a core file.
 | 
			
		||||
	CoreFileSize int
 | 
			
		||||
	// Limit of the process's resident set in pages.
 | 
			
		||||
	ResidentSet int
 | 
			
		||||
	// Maximum number of processes that can be created for the real user ID of
 | 
			
		||||
	// the calling process.
 | 
			
		||||
	Processes int
 | 
			
		||||
	// Value one greater than the maximum file descriptor number that can be
 | 
			
		||||
	// opened by this process.
 | 
			
		||||
	OpenFiles int
 | 
			
		||||
	// Maximum number of bytes of memory that may be locked into RAM.
 | 
			
		||||
	LockedMemory int
 | 
			
		||||
	// Maximum size of the process's virtual memory address space in bytes.
 | 
			
		||||
	AddressSpace int
 | 
			
		||||
	// Limit on the combined number of flock(2) locks and fcntl(2) leases that
 | 
			
		||||
	// this process may establish.
 | 
			
		||||
	FileLocks int
 | 
			
		||||
	// Limit of signals that may be queued for the real user ID of the calling
 | 
			
		||||
	// process.
 | 
			
		||||
	PendingSignals int
 | 
			
		||||
	// Limit on the number of bytes that can be allocated for POSIX message
 | 
			
		||||
	// queues for the real user ID of the calling process.
 | 
			
		||||
	MsqqueueSize int
 | 
			
		||||
	// Limit of the nice priority set using setpriority(2) or nice(2).
 | 
			
		||||
	NicePriority int
 | 
			
		||||
	// Limit of the real-time priority set using sched_setscheduler(2) or
 | 
			
		||||
	// sched_setparam(2).
 | 
			
		||||
	RealtimePriority int
 | 
			
		||||
	RealtimeTimeout  int
 | 
			
		||||
	// Limit (in microseconds) on the amount of CPU time that a process
 | 
			
		||||
	// scheduled under a real-time scheduling policy may consume without making
 | 
			
		||||
	// a blocking system call.
 | 
			
		||||
	RealtimeTimeout int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@@ -39,7 +66,7 @@ var (
 | 
			
		||||
 | 
			
		||||
// NewLimits returns the current soft limits of the process.
 | 
			
		||||
func (p Proc) NewLimits() (ProcLimits, error) {
 | 
			
		||||
	f, err := p.open("limits")
 | 
			
		||||
	f, err := os.Open(p.path("limits"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return ProcLimits{}, err
 | 
			
		||||
	}
 | 
			
		||||
@@ -60,7 +87,7 @@ func (p Proc) NewLimits() (ProcLimits, error) {
 | 
			
		||||
		case "Max cpu time":
 | 
			
		||||
			l.CPUTime, err = parseInt(fields[1])
 | 
			
		||||
		case "Max file size":
 | 
			
		||||
			l.FileLocks, err = parseInt(fields[1])
 | 
			
		||||
			l.FileSize, err = parseInt(fields[1])
 | 
			
		||||
		case "Max data size":
 | 
			
		||||
			l.DataSize, err = parseInt(fields[1])
 | 
			
		||||
		case "Max stack size":
 | 
			
		||||
@@ -90,7 +117,6 @@ func (p Proc) NewLimits() (ProcLimits, error) {
 | 
			
		||||
		case "Max realtime timeout":
 | 
			
		||||
			l.RealtimeTimeout, err = parseInt(fields[1])
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return ProcLimits{}, err
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								vendor/github.com/prometheus/procfs/proc_stat.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/prometheus/procfs/proc_stat.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -7,15 +7,15 @@ import (
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Originally, this USER_HZ value was dynamically retrieved via a sysconf call which
 | 
			
		||||
// required cgo. However, that caused a lot of problems regarding
 | 
			
		||||
// Originally, this USER_HZ value was dynamically retrieved via a sysconf call
 | 
			
		||||
// which required cgo. However, that caused a lot of problems regarding
 | 
			
		||||
// cross-compilation. Alternatives such as running a binary to determine the
 | 
			
		||||
// value, or trying to derive it in some other way were all problematic.
 | 
			
		||||
// After much research it was determined that USER_HZ is actually hardcoded to
 | 
			
		||||
// 100 on all Go-supported platforms as of the time of this writing. This is
 | 
			
		||||
// why we decided to hardcode it here as well. It is not impossible that there
 | 
			
		||||
// could be systems with exceptions, but they should be very exotic edge cases,
 | 
			
		||||
// and in that case, the worst outcome will be two misreported metrics.
 | 
			
		||||
// value, or trying to derive it in some other way were all problematic.  After
 | 
			
		||||
// much research it was determined that USER_HZ is actually hardcoded to 100 on
 | 
			
		||||
// all Go-supported platforms as of the time of this writing. This is why we
 | 
			
		||||
// decided to hardcode it here as well. It is not impossible that there could
 | 
			
		||||
// be systems with exceptions, but they should be very exotic edge cases, and
 | 
			
		||||
// in that case, the worst outcome will be two misreported metrics.
 | 
			
		||||
//
 | 
			
		||||
// See also the following discussions:
 | 
			
		||||
//
 | 
			
		||||
@@ -91,7 +91,7 @@ type ProcStat struct {
 | 
			
		||||
 | 
			
		||||
// NewStat returns the current status information of the process.
 | 
			
		||||
func (p Proc) NewStat() (ProcStat, error) {
 | 
			
		||||
	f, err := p.open("stat")
 | 
			
		||||
	f, err := os.Open(p.path("stat"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return ProcStat{}, err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/github.com/prometheus/procfs/stat.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/prometheus/procfs/stat.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -3,6 +3,7 @@ package procfs
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
@@ -25,7 +26,7 @@ func NewStat() (Stat, error) {
 | 
			
		||||
 | 
			
		||||
// NewStat returns an information about current kernel/system statistics.
 | 
			
		||||
func (fs FS) NewStat() (Stat, error) {
 | 
			
		||||
	f, err := fs.open("stat")
 | 
			
		||||
	f, err := os.Open(fs.Path("stat"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return Stat{}, err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										187
									
								
								vendor/github.com/prometheus/procfs/xfrm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								vendor/github.com/prometheus/procfs/xfrm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,187 @@
 | 
			
		||||
// Copyright 2017 Prometheus Team
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package procfs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// XfrmStat models the contents of /proc/net/xfrm_stat.
 | 
			
		||||
type XfrmStat struct {
 | 
			
		||||
	// All errors which are not matched by other
 | 
			
		||||
	XfrmInError int
 | 
			
		||||
	// No buffer is left
 | 
			
		||||
	XfrmInBufferError int
 | 
			
		||||
	// Header Error
 | 
			
		||||
	XfrmInHdrError int
 | 
			
		||||
	// No state found
 | 
			
		||||
	// i.e. either inbound SPI, address, or IPSEC protocol at SA is wrong
 | 
			
		||||
	XfrmInNoStates int
 | 
			
		||||
	// Transformation protocol specific error
 | 
			
		||||
	// e.g. SA Key is wrong
 | 
			
		||||
	XfrmInStateProtoError int
 | 
			
		||||
	// Transformation mode specific error
 | 
			
		||||
	XfrmInStateModeError int
 | 
			
		||||
	// Sequence error
 | 
			
		||||
	// e.g. sequence number is out of window
 | 
			
		||||
	XfrmInStateSeqError int
 | 
			
		||||
	// State is expired
 | 
			
		||||
	XfrmInStateExpired int
 | 
			
		||||
	// State has mismatch option
 | 
			
		||||
	// e.g. UDP encapsulation type is mismatched
 | 
			
		||||
	XfrmInStateMismatch int
 | 
			
		||||
	// State is invalid
 | 
			
		||||
	XfrmInStateInvalid int
 | 
			
		||||
	// No matching template for states
 | 
			
		||||
	// e.g. Inbound SAs are correct but SP rule is wrong
 | 
			
		||||
	XfrmInTmplMismatch int
 | 
			
		||||
	// No policy is found for states
 | 
			
		||||
	// e.g. Inbound SAs are correct but no SP is found
 | 
			
		||||
	XfrmInNoPols int
 | 
			
		||||
	// Policy discards
 | 
			
		||||
	XfrmInPolBlock int
 | 
			
		||||
	// Policy error
 | 
			
		||||
	XfrmInPolError int
 | 
			
		||||
	// All errors which are not matched by others
 | 
			
		||||
	XfrmOutError int
 | 
			
		||||
	// Bundle generation error
 | 
			
		||||
	XfrmOutBundleGenError int
 | 
			
		||||
	// Bundle check error
 | 
			
		||||
	XfrmOutBundleCheckError int
 | 
			
		||||
	// No state was found
 | 
			
		||||
	XfrmOutNoStates int
 | 
			
		||||
	// Transformation protocol specific error
 | 
			
		||||
	XfrmOutStateProtoError int
 | 
			
		||||
	// Transportation mode specific error
 | 
			
		||||
	XfrmOutStateModeError int
 | 
			
		||||
	// Sequence error
 | 
			
		||||
	// i.e sequence number overflow
 | 
			
		||||
	XfrmOutStateSeqError int
 | 
			
		||||
	// State is expired
 | 
			
		||||
	XfrmOutStateExpired int
 | 
			
		||||
	// Policy discads
 | 
			
		||||
	XfrmOutPolBlock int
 | 
			
		||||
	// Policy is dead
 | 
			
		||||
	XfrmOutPolDead int
 | 
			
		||||
	// Policy Error
 | 
			
		||||
	XfrmOutPolError     int
 | 
			
		||||
	XfrmFwdHdrError     int
 | 
			
		||||
	XfrmOutStateInvalid int
 | 
			
		||||
	XfrmAcquireError    int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewXfrmStat reads the xfrm_stat statistics.
 | 
			
		||||
func NewXfrmStat() (XfrmStat, error) {
 | 
			
		||||
	fs, err := NewFS(DefaultMountPoint)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return XfrmStat{}, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return fs.NewXfrmStat()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewXfrmStat reads the xfrm_stat statistics from the 'proc' filesystem.
 | 
			
		||||
func (fs FS) NewXfrmStat() (XfrmStat, error) {
 | 
			
		||||
	file, err := os.Open(fs.Path("net/xfrm_stat"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return XfrmStat{}, err
 | 
			
		||||
	}
 | 
			
		||||
	defer file.Close()
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		x = XfrmStat{}
 | 
			
		||||
		s = bufio.NewScanner(file)
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	for s.Scan() {
 | 
			
		||||
		fields := strings.Fields(s.Text())
 | 
			
		||||
 | 
			
		||||
		if len(fields) != 2 {
 | 
			
		||||
			return XfrmStat{}, fmt.Errorf(
 | 
			
		||||
				"couldnt parse %s line %s", file.Name(), s.Text())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		name := fields[0]
 | 
			
		||||
		value, err := strconv.Atoi(fields[1])
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return XfrmStat{}, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch name {
 | 
			
		||||
		case "XfrmInError":
 | 
			
		||||
			x.XfrmInError = value
 | 
			
		||||
		case "XfrmInBufferError":
 | 
			
		||||
			x.XfrmInBufferError = value
 | 
			
		||||
		case "XfrmInHdrError":
 | 
			
		||||
			x.XfrmInHdrError = value
 | 
			
		||||
		case "XfrmInNoStates":
 | 
			
		||||
			x.XfrmInNoStates = value
 | 
			
		||||
		case "XfrmInStateProtoError":
 | 
			
		||||
			x.XfrmInStateProtoError = value
 | 
			
		||||
		case "XfrmInStateModeError":
 | 
			
		||||
			x.XfrmInStateModeError = value
 | 
			
		||||
		case "XfrmInStateSeqError":
 | 
			
		||||
			x.XfrmInStateSeqError = value
 | 
			
		||||
		case "XfrmInStateExpired":
 | 
			
		||||
			x.XfrmInStateExpired = value
 | 
			
		||||
		case "XfrmInStateInvalid":
 | 
			
		||||
			x.XfrmInStateInvalid = value
 | 
			
		||||
		case "XfrmInTmplMismatch":
 | 
			
		||||
			x.XfrmInTmplMismatch = value
 | 
			
		||||
		case "XfrmInNoPols":
 | 
			
		||||
			x.XfrmInNoPols = value
 | 
			
		||||
		case "XfrmInPolBlock":
 | 
			
		||||
			x.XfrmInPolBlock = value
 | 
			
		||||
		case "XfrmInPolError":
 | 
			
		||||
			x.XfrmInPolError = value
 | 
			
		||||
		case "XfrmOutError":
 | 
			
		||||
			x.XfrmOutError = value
 | 
			
		||||
		case "XfrmInStateMismatch":
 | 
			
		||||
			x.XfrmInStateMismatch = value
 | 
			
		||||
		case "XfrmOutBundleGenError":
 | 
			
		||||
			x.XfrmOutBundleGenError = value
 | 
			
		||||
		case "XfrmOutBundleCheckError":
 | 
			
		||||
			x.XfrmOutBundleCheckError = value
 | 
			
		||||
		case "XfrmOutNoStates":
 | 
			
		||||
			x.XfrmOutNoStates = value
 | 
			
		||||
		case "XfrmOutStateProtoError":
 | 
			
		||||
			x.XfrmOutStateProtoError = value
 | 
			
		||||
		case "XfrmOutStateModeError":
 | 
			
		||||
			x.XfrmOutStateModeError = value
 | 
			
		||||
		case "XfrmOutStateSeqError":
 | 
			
		||||
			x.XfrmOutStateSeqError = value
 | 
			
		||||
		case "XfrmOutStateExpired":
 | 
			
		||||
			x.XfrmOutStateExpired = value
 | 
			
		||||
		case "XfrmOutPolBlock":
 | 
			
		||||
			x.XfrmOutPolBlock = value
 | 
			
		||||
		case "XfrmOutPolDead":
 | 
			
		||||
			x.XfrmOutPolDead = value
 | 
			
		||||
		case "XfrmOutPolError":
 | 
			
		||||
			x.XfrmOutPolError = value
 | 
			
		||||
		case "XfrmFwdHdrError":
 | 
			
		||||
			x.XfrmFwdHdrError = value
 | 
			
		||||
		case "XfrmOutStateInvalid":
 | 
			
		||||
			x.XfrmOutStateInvalid = value
 | 
			
		||||
		case "XfrmAcquireError":
 | 
			
		||||
			x.XfrmAcquireError = value
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return x, s.Err()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								vendor/github.com/prometheus/procfs/xfs/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/github.com/prometheus/procfs/xfs/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
package(default_visibility = ["//visibility:public"])
 | 
			
		||||
 | 
			
		||||
licenses(["notice"])
 | 
			
		||||
 | 
			
		||||
load(
 | 
			
		||||
    "@io_bazel_rules_go//go:def.bzl",
 | 
			
		||||
    "go_library",
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "parse.go",
 | 
			
		||||
        "xfs.go",
 | 
			
		||||
    ],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
    name = "package-srcs",
 | 
			
		||||
    srcs = glob(["**"]),
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
    visibility = ["//visibility:private"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
filegroup(
 | 
			
		||||
    name = "all-srcs",
 | 
			
		||||
    srcs = [":package-srcs"],
 | 
			
		||||
    tags = ["automanaged"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										359
									
								
								vendor/github.com/prometheus/procfs/xfs/parse.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										359
									
								
								vendor/github.com/prometheus/procfs/xfs/parse.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,359 @@
 | 
			
		||||
// Copyright 2017 The Prometheus Authors
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package xfs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ParseStats parses a Stats from an input io.Reader, using the format
 | 
			
		||||
// found in /proc/fs/xfs/stat.
 | 
			
		||||
func ParseStats(r io.Reader) (*Stats, error) {
 | 
			
		||||
	const (
 | 
			
		||||
		// Fields parsed into stats structures.
 | 
			
		||||
		fieldExtentAlloc = "extent_alloc"
 | 
			
		||||
		fieldAbt         = "abt"
 | 
			
		||||
		fieldBlkMap      = "blk_map"
 | 
			
		||||
		fieldBmbt        = "bmbt"
 | 
			
		||||
		fieldDir         = "dir"
 | 
			
		||||
		fieldTrans       = "trans"
 | 
			
		||||
		fieldIg          = "ig"
 | 
			
		||||
		fieldLog         = "log"
 | 
			
		||||
		fieldRw          = "rw"
 | 
			
		||||
		fieldAttr        = "attr"
 | 
			
		||||
		fieldIcluster    = "icluster"
 | 
			
		||||
		fieldVnodes      = "vnodes"
 | 
			
		||||
		fieldBuf         = "buf"
 | 
			
		||||
		fieldXpc         = "xpc"
 | 
			
		||||
 | 
			
		||||
		// Unimplemented at this time due to lack of documentation.
 | 
			
		||||
		fieldPushAil = "push_ail"
 | 
			
		||||
		fieldXstrat  = "xstrat"
 | 
			
		||||
		fieldAbtb2   = "abtb2"
 | 
			
		||||
		fieldAbtc2   = "abtc2"
 | 
			
		||||
		fieldBmbt2   = "bmbt2"
 | 
			
		||||
		fieldIbt2    = "ibt2"
 | 
			
		||||
		fieldFibt2   = "fibt2"
 | 
			
		||||
		fieldQm      = "qm"
 | 
			
		||||
		fieldDebug   = "debug"
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	var xfss Stats
 | 
			
		||||
 | 
			
		||||
	s := bufio.NewScanner(r)
 | 
			
		||||
	for s.Scan() {
 | 
			
		||||
		// Expect at least a string label and a single integer value, ex:
 | 
			
		||||
		//   - abt 0
 | 
			
		||||
		//   - rw 1 2
 | 
			
		||||
		ss := strings.Fields(string(s.Bytes()))
 | 
			
		||||
		if len(ss) < 2 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		label := ss[0]
 | 
			
		||||
 | 
			
		||||
		// Extended precision counters are uint64 values.
 | 
			
		||||
		if label == fieldXpc {
 | 
			
		||||
			us, err := parseUint64s(ss[1:])
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			xfss.ExtendedPrecision, err = extendedPrecisionStats(us)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// All other counters are uint32 values.
 | 
			
		||||
		us, err := parseUint32s(ss[1:])
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch label {
 | 
			
		||||
		case fieldExtentAlloc:
 | 
			
		||||
			xfss.ExtentAllocation, err = extentAllocationStats(us)
 | 
			
		||||
		case fieldAbt:
 | 
			
		||||
			xfss.AllocationBTree, err = btreeStats(us)
 | 
			
		||||
		case fieldBlkMap:
 | 
			
		||||
			xfss.BlockMapping, err = blockMappingStats(us)
 | 
			
		||||
		case fieldBmbt:
 | 
			
		||||
			xfss.BlockMapBTree, err = btreeStats(us)
 | 
			
		||||
		case fieldDir:
 | 
			
		||||
			xfss.DirectoryOperation, err = directoryOperationStats(us)
 | 
			
		||||
		case fieldTrans:
 | 
			
		||||
			xfss.Transaction, err = transactionStats(us)
 | 
			
		||||
		case fieldIg:
 | 
			
		||||
			xfss.InodeOperation, err = inodeOperationStats(us)
 | 
			
		||||
		case fieldLog:
 | 
			
		||||
			xfss.LogOperation, err = logOperationStats(us)
 | 
			
		||||
		case fieldRw:
 | 
			
		||||
			xfss.ReadWrite, err = readWriteStats(us)
 | 
			
		||||
		case fieldAttr:
 | 
			
		||||
			xfss.AttributeOperation, err = attributeOperationStats(us)
 | 
			
		||||
		case fieldIcluster:
 | 
			
		||||
			xfss.InodeClustering, err = inodeClusteringStats(us)
 | 
			
		||||
		case fieldVnodes:
 | 
			
		||||
			xfss.Vnode, err = vnodeStats(us)
 | 
			
		||||
		case fieldBuf:
 | 
			
		||||
			xfss.Buffer, err = bufferStats(us)
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &xfss, s.Err()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// extentAllocationStats builds an ExtentAllocationStats from a slice of uint32s.
 | 
			
		||||
func extentAllocationStats(us []uint32) (ExtentAllocationStats, error) {
 | 
			
		||||
	if l := len(us); l != 4 {
 | 
			
		||||
		return ExtentAllocationStats{}, fmt.Errorf("incorrect number of values for XFS extent allocation stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ExtentAllocationStats{
 | 
			
		||||
		ExtentsAllocated: us[0],
 | 
			
		||||
		BlocksAllocated:  us[1],
 | 
			
		||||
		ExtentsFreed:     us[2],
 | 
			
		||||
		BlocksFreed:      us[3],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// btreeStats builds a BTreeStats from a slice of uint32s.
 | 
			
		||||
func btreeStats(us []uint32) (BTreeStats, error) {
 | 
			
		||||
	if l := len(us); l != 4 {
 | 
			
		||||
		return BTreeStats{}, fmt.Errorf("incorrect number of values for XFS btree stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return BTreeStats{
 | 
			
		||||
		Lookups:         us[0],
 | 
			
		||||
		Compares:        us[1],
 | 
			
		||||
		RecordsInserted: us[2],
 | 
			
		||||
		RecordsDeleted:  us[3],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BlockMappingStat builds a BlockMappingStats from a slice of uint32s.
 | 
			
		||||
func blockMappingStats(us []uint32) (BlockMappingStats, error) {
 | 
			
		||||
	if l := len(us); l != 7 {
 | 
			
		||||
		return BlockMappingStats{}, fmt.Errorf("incorrect number of values for XFS block mapping stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return BlockMappingStats{
 | 
			
		||||
		Reads:                us[0],
 | 
			
		||||
		Writes:               us[1],
 | 
			
		||||
		Unmaps:               us[2],
 | 
			
		||||
		ExtentListInsertions: us[3],
 | 
			
		||||
		ExtentListDeletions:  us[4],
 | 
			
		||||
		ExtentListLookups:    us[5],
 | 
			
		||||
		ExtentListCompares:   us[6],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DirectoryOperationStats builds a DirectoryOperationStats from a slice of uint32s.
 | 
			
		||||
func directoryOperationStats(us []uint32) (DirectoryOperationStats, error) {
 | 
			
		||||
	if l := len(us); l != 4 {
 | 
			
		||||
		return DirectoryOperationStats{}, fmt.Errorf("incorrect number of values for XFS directory operation stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return DirectoryOperationStats{
 | 
			
		||||
		Lookups:  us[0],
 | 
			
		||||
		Creates:  us[1],
 | 
			
		||||
		Removes:  us[2],
 | 
			
		||||
		Getdents: us[3],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TransactionStats builds a TransactionStats from a slice of uint32s.
 | 
			
		||||
func transactionStats(us []uint32) (TransactionStats, error) {
 | 
			
		||||
	if l := len(us); l != 3 {
 | 
			
		||||
		return TransactionStats{}, fmt.Errorf("incorrect number of values for XFS transaction stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TransactionStats{
 | 
			
		||||
		Sync:  us[0],
 | 
			
		||||
		Async: us[1],
 | 
			
		||||
		Empty: us[2],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InodeOperationStats builds an InodeOperationStats from a slice of uint32s.
 | 
			
		||||
func inodeOperationStats(us []uint32) (InodeOperationStats, error) {
 | 
			
		||||
	if l := len(us); l != 7 {
 | 
			
		||||
		return InodeOperationStats{}, fmt.Errorf("incorrect number of values for XFS inode operation stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return InodeOperationStats{
 | 
			
		||||
		Attempts:        us[0],
 | 
			
		||||
		Found:           us[1],
 | 
			
		||||
		Recycle:         us[2],
 | 
			
		||||
		Missed:          us[3],
 | 
			
		||||
		Duplicate:       us[4],
 | 
			
		||||
		Reclaims:        us[5],
 | 
			
		||||
		AttributeChange: us[6],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LogOperationStats builds a LogOperationStats from a slice of uint32s.
 | 
			
		||||
func logOperationStats(us []uint32) (LogOperationStats, error) {
 | 
			
		||||
	if l := len(us); l != 5 {
 | 
			
		||||
		return LogOperationStats{}, fmt.Errorf("incorrect number of values for XFS log operation stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return LogOperationStats{
 | 
			
		||||
		Writes:            us[0],
 | 
			
		||||
		Blocks:            us[1],
 | 
			
		||||
		NoInternalBuffers: us[2],
 | 
			
		||||
		Force:             us[3],
 | 
			
		||||
		ForceSleep:        us[4],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ReadWriteStats builds a ReadWriteStats from a slice of uint32s.
 | 
			
		||||
func readWriteStats(us []uint32) (ReadWriteStats, error) {
 | 
			
		||||
	if l := len(us); l != 2 {
 | 
			
		||||
		return ReadWriteStats{}, fmt.Errorf("incorrect number of values for XFS read write stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ReadWriteStats{
 | 
			
		||||
		Read:  us[0],
 | 
			
		||||
		Write: us[1],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AttributeOperationStats builds an AttributeOperationStats from a slice of uint32s.
 | 
			
		||||
func attributeOperationStats(us []uint32) (AttributeOperationStats, error) {
 | 
			
		||||
	if l := len(us); l != 4 {
 | 
			
		||||
		return AttributeOperationStats{}, fmt.Errorf("incorrect number of values for XFS attribute operation stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return AttributeOperationStats{
 | 
			
		||||
		Get:    us[0],
 | 
			
		||||
		Set:    us[1],
 | 
			
		||||
		Remove: us[2],
 | 
			
		||||
		List:   us[3],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InodeClusteringStats builds an InodeClusteringStats from a slice of uint32s.
 | 
			
		||||
func inodeClusteringStats(us []uint32) (InodeClusteringStats, error) {
 | 
			
		||||
	if l := len(us); l != 3 {
 | 
			
		||||
		return InodeClusteringStats{}, fmt.Errorf("incorrect number of values for XFS inode clustering stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return InodeClusteringStats{
 | 
			
		||||
		Iflush:     us[0],
 | 
			
		||||
		Flush:      us[1],
 | 
			
		||||
		FlushInode: us[2],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VnodeStats builds a VnodeStats from a slice of uint32s.
 | 
			
		||||
func vnodeStats(us []uint32) (VnodeStats, error) {
 | 
			
		||||
	// The attribute "Free" appears to not be available on older XFS
 | 
			
		||||
	// stats versions.  Therefore, 7 or 8 elements may appear in
 | 
			
		||||
	// this slice.
 | 
			
		||||
	l := len(us)
 | 
			
		||||
	if l != 7 && l != 8 {
 | 
			
		||||
		return VnodeStats{}, fmt.Errorf("incorrect number of values for XFS vnode stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s := VnodeStats{
 | 
			
		||||
		Active:   us[0],
 | 
			
		||||
		Allocate: us[1],
 | 
			
		||||
		Get:      us[2],
 | 
			
		||||
		Hold:     us[3],
 | 
			
		||||
		Release:  us[4],
 | 
			
		||||
		Reclaim:  us[5],
 | 
			
		||||
		Remove:   us[6],
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Skip adding free, unless it is present. The zero value will
 | 
			
		||||
	// be used in place of an actual count.
 | 
			
		||||
	if l == 7 {
 | 
			
		||||
		return s, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.Free = us[7]
 | 
			
		||||
	return s, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BufferStats builds a BufferStats from a slice of uint32s.
 | 
			
		||||
func bufferStats(us []uint32) (BufferStats, error) {
 | 
			
		||||
	if l := len(us); l != 9 {
 | 
			
		||||
		return BufferStats{}, fmt.Errorf("incorrect number of values for XFS buffer stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return BufferStats{
 | 
			
		||||
		Get:             us[0],
 | 
			
		||||
		Create:          us[1],
 | 
			
		||||
		GetLocked:       us[2],
 | 
			
		||||
		GetLockedWaited: us[3],
 | 
			
		||||
		BusyLocked:      us[4],
 | 
			
		||||
		MissLocked:      us[5],
 | 
			
		||||
		PageRetries:     us[6],
 | 
			
		||||
		PageFound:       us[7],
 | 
			
		||||
		GetRead:         us[8],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ExtendedPrecisionStats builds an ExtendedPrecisionStats from a slice of uint32s.
 | 
			
		||||
func extendedPrecisionStats(us []uint64) (ExtendedPrecisionStats, error) {
 | 
			
		||||
	if l := len(us); l != 3 {
 | 
			
		||||
		return ExtendedPrecisionStats{}, fmt.Errorf("incorrect number of values for XFS extended precision stats: %d", l)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ExtendedPrecisionStats{
 | 
			
		||||
		FlushBytes: us[0],
 | 
			
		||||
		WriteBytes: us[1],
 | 
			
		||||
		ReadBytes:  us[2],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseUint32s parses a slice of strings into a slice of uint32s.
 | 
			
		||||
func parseUint32s(ss []string) ([]uint32, error) {
 | 
			
		||||
	us := make([]uint32, 0, len(ss))
 | 
			
		||||
	for _, s := range ss {
 | 
			
		||||
		u, err := strconv.ParseUint(s, 10, 32)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		us = append(us, uint32(u))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return us, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parseUint64s parses a slice of strings into a slice of uint64s.
 | 
			
		||||
func parseUint64s(ss []string) ([]uint64, error) {
 | 
			
		||||
	us := make([]uint64, 0, len(ss))
 | 
			
		||||
	for _, s := range ss {
 | 
			
		||||
		u, err := strconv.ParseUint(s, 10, 64)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		us = append(us, u)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return us, nil
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user