func (cw *catchStatus) WriteHeader(code int) {
	cw.ResponseWriter.WriteHeader(code)
	cw.status = code
}
WriteHeader wraps the http.ResponseWriter.WriteHeader method, and preserves the
status code.
package metrics
import (
	"fmt"
	"log"
	"math"
	"net/http"
	"runtime"
	"runtime/debug"
	"time"
	"github.com/m-lab/etl/etl"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
)
func init() {
	NumCPU.Set(float64(runtime.NumCPU()))
	CommitHash.WithLabelValues(etl.GitCommit).Set(1)
	ReleaseTag.WithLabelValues(etl.Version).Set(1)
}
var (
	CommitHash = promauto.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "etl_commit_hash",
			Help: "Commit hash from repo build",
		}, []string{"value"})
	ReleaseTag = promauto.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "etl_release_tag",
			Help: "Release tag from repo build",
		}, []string{"value"})
	NumCPU = promauto.NewGauge(
		prometheus.GaugeOpts{
			Name: "etl_num_cpu",
			Help: "Number of cpus available to process.",
		})
	ActiveErrors = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_active_error_total",
			Help: "The current number of errors encountered while attempting to add annotation data.",
		}, []string{"source", "type"})
	ActiveTasks = promauto.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "etl_active_tasks",
			Help: "Number of active tasks in flight.",
		},
		[]string{"source"})
	AnnotationTimeSummary = promauto.NewSummaryVec(prometheus.SummaryOpts{
		Name: "etl_annotator_Annotation_Time_Summary",
		Help: "The total time to annotate, in nanoseconds.",
	}, []string{"test_type"})
	AnnotationRequestCount = promauto.NewGauge(prometheus.GaugeOpts{
		Name: "etl_annotator_Request_Count",
		Help: "The current number of annotation requests",
	})
	AnnotationErrorCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_annotator_Error_Count",
			Help: "The current number of errors encountered while attempting to add annotation data.",
		}, []string{"source"})
	AnnotationWarningCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_annotator_Warning_Count",
			Help: "The current number of Warnings encountered while attempting to add annotation data.",
		}, []string{"source"})
	AnnotationMissingCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_annotation_missing_total",
			Help: "The current number of IPs with missing annotation data.",
		}, []string{"type"})
	PanicCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_panic_count",
			Help: "Number of panics encountered.",
		},
		[]string{"source"},
	)
	WorkerCount = promauto.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "etl_worker_count",
			Help: "Number of active workers.",
		},
		[]string{"table"})
	WorkerState = promauto.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "etl_worker_state",
			Help: "Number of workers in different states.",
		},
		[]string{"table", "state"},
	)
	FileCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_files_processed",
			Help: "Number of files processed.",
		},
		[]string{"rsync_host_module", "day_of_week"},
	)
	TaskCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_task_count",
			Help: "Number of tasks/archive files processed.",
		},
		[]string{"table", "status"},
	)
	TestCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_test_count",
			Help: "Number of tests processed.",
		},
		[]string{"table", "filetype", "status"},
	)
	PTHopCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_pthop_count",
			Help: "Number of hops for PT tests processed.",
		},
		[]string{"table", "filetype", "status"},
	)
	PTTestCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_pt_test_count_per_metro",
			Help: "Count how many PT tests per metro.",
		},
		[]string{"metro"},
	)
	PTNotReachDestCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_pt_not_reach_dest_count",
			Help: "Count how many PT tests did not reach expected destination at the last hop per metro.",
		},
		[]string{"metro"},
	)
	PTMoreHopsAfterDest = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_pt_more_hops_after_dest_count",
			Help: "Count how many PT tests reach expected destination in middle but do more hops afterwards instead of ending there.",
		},
		[]string{"metro"},
	)
	PTBitsAwayFromDestV4 = promauto.NewHistogramVec(
		prometheus.HistogramOpts{
			Name: "etl_pt_bits_away_from_dest_v4",
			Help: "Bits diff distribution between last hop and expected destination IP for IPv4.",
			Buckets: []float64{
				0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
			},
		},
		[]string{"metro"},
	)
	PTBitsAwayFromDestV6 = promauto.NewHistogramVec(
		prometheus.HistogramOpts{
			Name: "etl_pt_bits_away_from_dest_v6",
			Help: "Bits diff distribution between last hop and expected destination IP for IPv6.",
			Buckets: []float64{
				0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
			},
		},
		[]string{"metro"},
	)
	PTPollutedCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_pt_polluted_total",
			Help: "Count how many PT tests polluted per metro.",
		},
		[]string{"metro"},
	)
	WarningCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_warning_count",
			Help: "Warnings that do not result in test loss.",
		},
		[]string{"table", "filetype", "kind"},
	)
	ErrorCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_error_count",
			Help: "Errors that cause test loss.",
		},
		[]string{"table", "filetype", "kind"},
	)
	BackendFailureCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_backend_failure_count",
			Help: "Backend failures, whether or not recoverable.",
		},
		[]string{"table", "kind"},
	)
	GCSRetryCount = promauto.NewCounterVec(
		prometheus.CounterOpts{
			Name: "etl_gcs_retry_count",
			Help: "Number of retries on GCS reads.",
		},
		[]string{"table", "phase", "retries", "status"},
	)
	RowSizeHistogram = promauto.NewHistogramVec(
		prometheus.HistogramOpts{
			Name: "etl_row_json_size",
			Help: "Row json size distributions.",
			Buckets: []float64{
				100, 200, 400, 800, 1600, 3200, 6400, 10000, 20000,
				40000, 80000, 160000, 320000, 500000, 600000, 700000,
				800000, 900000, 1000000, 1200000, 1500000, 2000000, 5000000,
			},
		},
		[]string{"table"},
	)
	DeltaNumFieldsHistogram = promauto.NewHistogramVec(
		prometheus.HistogramOpts{
			Name: "etl_delta_num_field",
			Help: "Number of fields in delta distribution.",
			Buckets: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
				14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 50, 60, 70, 80, 90,
				100, 110, 120, 150,
			},
		},
		[]string{"table"},
	)
	EntryFieldCountHistogram = promauto.NewHistogramVec(
		prometheus.HistogramOpts{
			Name: "etl_entry_field_count",
			Help: "total snapshot field count distributions.",
			Buckets: []float64{
				1, 2, 3, 4, 6, 8,
				10, 12, 15, 20, 24, 30, 40, 48, 60, 80,
				100, 120, 150, 200, 240, 300, 400, 480, 600, 800,
				1000, 1200, 1500, 2000, 2400, 3000, 4000, 4800, 6000, 8000,
				10000, 12000, 15000, 20000, 24000, 30000, 40000, 48000, 60000, 80000,
				100000, 120000, 150000, 200000, 240000, 300000, 400000, 480000,
			},
		},
		[]string{"table"},
	)
	InsertionHistogram = promauto.NewHistogramVec(
		prometheus.HistogramOpts{
			Name: "etl_insertion_time_seconds",
			Help: "Insertion time distributions.",
			Buckets: []float64{
				0.001, 0.003, 0.01, 0.03, 0.1, 0.2, 0.5, 1.0, 2.0,
				5.0, 10.0, 20.0, 50.0, 100.0, 200.0, math.Inf(+1),
			},
		},
		[]string{"table", "status"},
	)
	DurationHistogram = promauto.NewHistogramVec(
		prometheus.HistogramOpts{
			Name: "etl_worker_duration_seconds",
			Help: "Worker execution time distributions.",
			Buckets: []float64{
				1, 1.4, 2.0, 2.7, 3.7, 5.2, 7.2,
				10, 14, 20, 27, 37, 52, 72,
				100, 140, 200, 270, 370, 520, 720,
				1000, 1400, 2000, 2700, 3700, 5200, 7200,
			},
		},
		[]string{"worker", "status"},
	)
	FileSizeHistogram = promauto.NewHistogramVec(
		prometheus.HistogramOpts{
			Name: "etl_test_file_size_bytes",
			Help: "Size of individual test files.",
			Buckets: []float64{
				0,
				1000,        
				5000,        
				10000,       
				25000,       
				50000,       
				75000,       
				100000,      
				200000,      
				300000,      
				400000,      
				500000,      
				600000,      
				700000,      
				800000,      
				900000,      
				1000000,     
				1100000,     
				1200000,     
				1400000,     
				1600000,     
				1800000,     
				2000000,     
				2400000,     
				2800000,     
				3200000,     
				3600000,     
				4000000,     
				6000000,     
				8000000,     
				10000000,    
				20000000,    
				40000000,    
				80000000,    
				100000000,   
				200000000,   
				400000000,   
				800000000,   
				1000000000,  
				math.Inf(+1),
			},
		},
		[]string{"table", "kind", "group"},
	)
)
type catchStatus struct {
	http.ResponseWriter
	status int
}