Browse code

vendor: bump prometheus/common v0.7.0

full diff: https://github.com/prometheus/common/compare/7600349dcfe1abd18d72d3a1770870d9800a7801...v0.7.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2020/01/09 09:03:43
Showing 8 changed files
... ...
@@ -146,7 +146,7 @@ code.cloudfoundry.org/clock                         02e53af36e6c978af692887ed449
146 146
 github.com/prometheus/client_golang                 c5b7fccd204277076155f10851dad72b76a49317 # v0.8.0
147 147
 github.com/beorn7/perks                             37c8de3658fcb183f997c4e13e8337516ab753e6 # v1.0.1
148 148
 github.com/prometheus/client_model                  d1d2010b5beead3fa1c5f271a5cf626e40b3ad6e # v0.1.0
149
-github.com/prometheus/common                        7600349dcfe1abd18d72d3a1770870d9800a7801
149
+github.com/prometheus/common                        287d3e634a1e550c9e463dd7e5a75a422c614505 # v0.7.0
150 150
 github.com/prometheus/procfs                        7d6f385de8bea29190f15ba9931442a0eaef9af7
151 151
 github.com/matttproud/golang_protobuf_extensions    c12348ce28de40eed0136aa2b644d0ee0650e56c # v1.0.1
152 152
 github.com/pkg/errors                               ba968bfe8b2f7e042a574c888954fccecfa385b4 # v0.8.1
... ...
@@ -6,7 +6,11 @@ components and libraries.
6 6
 
7 7
 * **config**: Common configuration structures
8 8
 * **expfmt**: Decoding and encoding for the exposition format
9
-* **log**: A logging wrapper around [logrus](https://github.com/sirupsen/logrus)
10 9
 * **model**: Shared data structures
10
+* **promlog**: A logging wrapper around [go-kit/log](https://github.com/go-kit/kit/tree/master/log)
11 11
 * **route**: A routing wrapper around [httprouter](https://github.com/julienschmidt/httprouter) using `context.Context`
12
+* **server**: Common servers
12 13
 * **version**: Version information and metrics
14
+
15
+## Deprecated
16
+* **log**: A logging wrapper around [logrus](https://github.com/sirupsen/logrus)
... ...
@@ -14,13 +14,45 @@
14 14
 package expfmt
15 15
 
16 16
 import (
17
+	"bufio"
17 18
 	"fmt"
18 19
 	"io"
20
+	"io/ioutil"
19 21
 	"math"
22
+	"strconv"
20 23
 	"strings"
24
+	"sync"
21 25
 
22
-	dto "github.com/prometheus/client_model/go"
23 26
 	"github.com/prometheus/common/model"
27
+
28
+	dto "github.com/prometheus/client_model/go"
29
+)
30
+
31
+// enhancedWriter has all the enhanced write functions needed here. bufio.Writer
32
+// implements it.
33
+type enhancedWriter interface {
34
+	io.Writer
35
+	WriteRune(r rune) (n int, err error)
36
+	WriteString(s string) (n int, err error)
37
+	WriteByte(c byte) error
38
+}
39
+
40
+const (
41
+	initialNumBufSize = 24
42
+)
43
+
44
+var (
45
+	bufPool = sync.Pool{
46
+		New: func() interface{} {
47
+			return bufio.NewWriter(ioutil.Discard)
48
+		},
49
+	}
50
+	numBufPool = sync.Pool{
51
+		New: func() interface{} {
52
+			b := make([]byte, 0, initialNumBufSize)
53
+			return &b
54
+		},
55
+	}
24 56
 )
25 57
 
26 58
 // MetricFamilyToText converts a MetricFamily proto message into text format and
... ...
@@ -32,37 +64,90 @@ import (
32 32
 // will result in invalid text format output.
33 33
 //
34 34
 // This method fulfills the type 'prometheus.encoder'.
35
-func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
36
-	var written int
37
-
35
+func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (written int, err error) {
38 36
 	// Fail-fast checks.
39 37
 	if len(in.Metric) == 0 {
40
-		return written, fmt.Errorf("MetricFamily has no metrics: %s", in)
38
+		return 0, fmt.Errorf("MetricFamily has no metrics: %s", in)
41 39
 	}
42 40
 	name := in.GetName()
43 41
 	if name == "" {
44
-		return written, fmt.Errorf("MetricFamily has no name: %s", in)
42
+		return 0, fmt.Errorf("MetricFamily has no name: %s", in)
43
+	}
44
+
45
+	// Try the interface upgrade. If it doesn't work, we'll use a
46
+	// bufio.Writer from the sync.Pool.
47
+	w, ok := out.(enhancedWriter)
48
+	if !ok {
49
+		b := bufPool.Get().(*bufio.Writer)
50
+		b.Reset(out)
51
+		w = b
52
+		defer func() {
53
+			bErr := b.Flush()
54
+			if err == nil {
55
+				err = bErr
56
+			}
57
+			bufPool.Put(b)
58
+		}()
45 59
 	}
46 60
 
61
+	var n int
62
+
47 63
 	// Comments, first HELP, then TYPE.
48 64
 	if in.Help != nil {
49
-		n, err := fmt.Fprintf(
50
-			out, "# HELP %s %s\n",
51
-			name, escapeString(*in.Help, false),
52
-		)
65
+		n, err = w.WriteString("# HELP ")
53 66
 		written += n
54 67
 		if err != nil {
55
-			return written, err
68
+			return
69
+		}
70
+		n, err = w.WriteString(name)
71
+		written += n
72
+		if err != nil {
73
+			return
74
+		}
75
+		err = w.WriteByte(' ')
76
+		written++
77
+		if err != nil {
78
+			return
56 79
 		}
80
+		n, err = writeEscapedString(w, *in.Help, false)
81
+		written += n
82
+		if err != nil {
83
+			return
84
+		}
85
+		err = w.WriteByte('\n')
86
+		written++
87
+		if err != nil {
88
+			return
89
+		}
90
+	}
91
+	n, err = w.WriteString("# TYPE ")
92
+	written += n
93
+	if err != nil {
94
+		return
95
+	}
96
+	n, err = w.WriteString(name)
97
+	written += n
98
+	if err != nil {
99
+		return
57 100
 	}
58 101
 	metricType := in.GetType()
59
-	n, err := fmt.Fprintf(
60
-		out, "# TYPE %s %s\n",
61
-		name, strings.ToLower(metricType.String()),
62
-	)
102
+	switch metricType {
103
+	case dto.MetricType_COUNTER:
104
+		n, err = w.WriteString(" counter\n")
105
+	case dto.MetricType_GAUGE:
106
+		n, err = w.WriteString(" gauge\n")
107
+	case dto.MetricType_SUMMARY:
108
+		n, err = w.WriteString(" summary\n")
109
+	case dto.MetricType_UNTYPED:
110
+		n, err = w.WriteString(" untyped\n")
111
+	case dto.MetricType_HISTOGRAM:
112
+		n, err = w.WriteString(" histogram\n")
113
+	default:
114
+		return written, fmt.Errorf("unknown metric type %s", metricType.String())
115
+	}
63 116
 	written += n
64 117
 	if err != nil {
65
-		return written, err
118
+		return
66 119
 	}
67 120
 
68 121
 	// Finally the samples, one line for each.
... ...
@@ -75,9 +160,8 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
75 75
 				)
76 76
 			}
77 77
 			n, err = writeSample(
78
-				name, metric, "", "",
78
+				w, name, "", metric, "", 0,
79 79
 				metric.Counter.GetValue(),
80
-				out,
81 80
 			)
82 81
 		case dto.MetricType_GAUGE:
83 82
 			if metric.Gauge == nil {
... ...
@@ -86,9 +170,8 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
86 86
 				)
87 87
 			}
88 88
 			n, err = writeSample(
89
-				name, metric, "", "",
89
+				w, name, "", metric, "", 0,
90 90
 				metric.Gauge.GetValue(),
91
-				out,
92 91
 			)
93 92
 		case dto.MetricType_UNTYPED:
94 93
 			if metric.Untyped == nil {
... ...
@@ -97,9 +180,8 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
97 97
 				)
98 98
 			}
99 99
 			n, err = writeSample(
100
-				name, metric, "", "",
100
+				w, name, "", metric, "", 0,
101 101
 				metric.Untyped.GetValue(),
102
-				out,
103 102
 			)
104 103
 		case dto.MetricType_SUMMARY:
105 104
 			if metric.Summary == nil {
... ...
@@ -109,29 +191,26 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
109 109
 			}
110 110
 			for _, q := range metric.Summary.Quantile {
111 111
 				n, err = writeSample(
112
-					name, metric,
113
-					model.QuantileLabel, fmt.Sprint(q.GetQuantile()),
112
+					w, name, "", metric,
113
+					model.QuantileLabel, q.GetQuantile(),
114 114
 					q.GetValue(),
115
-					out,
116 115
 				)
117 116
 				written += n
118 117
 				if err != nil {
119
-					return written, err
118
+					return
120 119
 				}
121 120
 			}
122 121
 			n, err = writeSample(
123
-				name+"_sum", metric, "", "",
122
+				w, name, "_sum", metric, "", 0,
124 123
 				metric.Summary.GetSampleSum(),
125
-				out,
126 124
 			)
125
+			written += n
127 126
 			if err != nil {
128
-				return written, err
127
+				return
129 128
 			}
130
-			written += n
131 129
 			n, err = writeSample(
132
-				name+"_count", metric, "", "",
130
+				w, name, "_count", metric, "", 0,
133 131
 				float64(metric.Summary.GetSampleCount()),
134
-				out,
135 132
 			)
136 133
 		case dto.MetricType_HISTOGRAM:
137 134
 			if metric.Histogram == nil {
... ...
@@ -140,46 +219,42 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
140 140
 				)
141 141
 			}
142 142
 			infSeen := false
143
-			for _, q := range metric.Histogram.Bucket {
143
+			for _, b := range metric.Histogram.Bucket {
144 144
 				n, err = writeSample(
145
-					name+"_bucket", metric,
146
-					model.BucketLabel, fmt.Sprint(q.GetUpperBound()),
147
-					float64(q.GetCumulativeCount()),
148
-					out,
145
+					w, name, "_bucket", metric,
146
+					model.BucketLabel, b.GetUpperBound(),
147
+					float64(b.GetCumulativeCount()),
149 148
 				)
150 149
 				written += n
151 150
 				if err != nil {
152
-					return written, err
151
+					return
153 152
 				}
154
-				if math.IsInf(q.GetUpperBound(), +1) {
153
+				if math.IsInf(b.GetUpperBound(), +1) {
155 154
 					infSeen = true
156 155
 				}
157 156
 			}
158 157
 			if !infSeen {
159 158
 				n, err = writeSample(
160
-					name+"_bucket", metric,
161
-					model.BucketLabel, "+Inf",
159
+					w, name, "_bucket", metric,
160
+					model.BucketLabel, math.Inf(+1),
162 161
 					float64(metric.Histogram.GetSampleCount()),
163
-					out,
164 162
 				)
163
+				written += n
165 164
 				if err != nil {
166
-					return written, err
165
+					return
167 166
 				}
168
-				written += n
169 167
 			}
170 168
 			n, err = writeSample(
171
-				name+"_sum", metric, "", "",
169
+				w, name, "_sum", metric, "", 0,
172 170
 				metric.Histogram.GetSampleSum(),
173
-				out,
174 171
 			)
172
+			written += n
175 173
 			if err != nil {
176
-				return written, err
174
+				return
177 175
 			}
178
-			written += n
179 176
 			n, err = writeSample(
180
-				name+"_count", metric, "", "",
177
+				w, name, "_count", metric, "", 0,
181 178
 				float64(metric.Histogram.GetSampleCount()),
182
-				out,
183 179
 			)
184 180
 		default:
185 181
 			return written, fmt.Errorf(
... ...
@@ -188,116 +263,204 @@ func MetricFamilyToText(out io.Writer, in *dto.MetricFamily) (int, error) {
188 188
 		}
189 189
 		written += n
190 190
 		if err != nil {
191
-			return written, err
191
+			return
192 192
 		}
193 193
 	}
194
-	return written, nil
194
+	return
195 195
 }
196 196
 
197
-// writeSample writes a single sample in text format to out, given the metric
197
+// writeSample writes a single sample in text format to w, given the metric
198 198
 // name, the metric proto message itself, optionally an additional label name
199
-// and value (use empty strings if not required), and the value. The function
200
-// returns the number of bytes written and any error encountered.
199
+// with a float64 value (use empty string as label name if not required), and
200
+// the value. The function returns the number of bytes written and any error
201
+// encountered.
201 202
 func writeSample(
202
-	name string,
203
+	w enhancedWriter,
204
+	name, suffix string,
203 205
 	metric *dto.Metric,
204
-	additionalLabelName, additionalLabelValue string,
206
+	additionalLabelName string, additionalLabelValue float64,
205 207
 	value float64,
206
-	out io.Writer,
207 208
 ) (int, error) {
208 209
 	var written int
209
-	n, err := fmt.Fprint(out, name)
210
+	n, err := w.WriteString(name)
210 211
 	written += n
211 212
 	if err != nil {
212 213
 		return written, err
213 214
 	}
214
-	n, err = labelPairsToText(
215
-		metric.Label,
216
-		additionalLabelName, additionalLabelValue,
217
-		out,
215
+	if suffix != "" {
216
+		n, err = w.WriteString(suffix)
217
+		written += n
218
+		if err != nil {
219
+			return written, err
220
+		}
221
+	}
222
+	n, err = writeLabelPairs(
223
+		w, metric.Label, additionalLabelName, additionalLabelValue,
218 224
 	)
219 225
 	written += n
220 226
 	if err != nil {
221 227
 		return written, err
222 228
 	}
223
-	n, err = fmt.Fprintf(out, " %v", value)
229
+	err = w.WriteByte(' ')
230
+	written++
231
+	if err != nil {
232
+		return written, err
233
+	}
234
+	n, err = writeFloat(w, value)
224 235
 	written += n
225 236
 	if err != nil {
226 237
 		return written, err
227 238
 	}
228 239
 	if metric.TimestampMs != nil {
229
-		n, err = fmt.Fprintf(out, " %v", *metric.TimestampMs)
240
+		err = w.WriteByte(' ')
241
+		written++
242
+		if err != nil {
243
+			return written, err
244
+		}
245
+		n, err = writeInt(w, *metric.TimestampMs)
230 246
 		written += n
231 247
 		if err != nil {
232 248
 			return written, err
233 249
 		}
234 250
 	}
235
-	n, err = out.Write([]byte{'\n'})
236
-	written += n
251
+	err = w.WriteByte('\n')
252
+	written++
237 253
 	if err != nil {
238 254
 		return written, err
239 255
 	}
240 256
 	return written, nil
241 257
 }
242 258
 
243
-// labelPairsToText converts a slice of LabelPair proto messages plus the
259
+// writeLabelPairs converts a slice of LabelPair proto messages plus the
244 260
 // explicitly given additional label pair into text formatted as required by the
245
-// text format and writes it to 'out'. An empty slice in combination with an
246
-// empty string 'additionalLabelName' results in nothing being
247
-// written. Otherwise, the label pairs are written, escaped as required by the
248
-// text format, and enclosed in '{...}'. The function returns the number of
249
-// bytes written and any error encountered.
250
-func labelPairsToText(
261
+// text format and writes it to 'w'. An empty slice in combination with an empty
262
+// string 'additionalLabelName' results in nothing being written. Otherwise, the
263
+// label pairs are written, escaped as required by the text format, and enclosed
264
+// in '{...}'. The function returns the number of bytes written and any error
265
+// encountered.
266
+func writeLabelPairs(
267
+	w enhancedWriter,
251 268
 	in []*dto.LabelPair,
252
-	additionalLabelName, additionalLabelValue string,
253
-	out io.Writer,
269
+	additionalLabelName string, additionalLabelValue float64,
254 270
 ) (int, error) {
255 271
 	if len(in) == 0 && additionalLabelName == "" {
256 272
 		return 0, nil
257 273
 	}
258
-	var written int
259
-	separator := '{'
274
+	var (
275
+		written   int
276
+		separator byte = '{'
277
+	)
260 278
 	for _, lp := range in {
261
-		n, err := fmt.Fprintf(
262
-			out, `%c%s="%s"`,
263
-			separator, lp.GetName(), escapeString(lp.GetValue(), true),
264
-		)
279
+		err := w.WriteByte(separator)
280
+		written++
281
+		if err != nil {
282
+			return written, err
283
+		}
284
+		n, err := w.WriteString(lp.GetName())
285
+		written += n
286
+		if err != nil {
287
+			return written, err
288
+		}
289
+		n, err = w.WriteString(`="`)
290
+		written += n
291
+		if err != nil {
292
+			return written, err
293
+		}
294
+		n, err = writeEscapedString(w, lp.GetValue(), true)
265 295
 		written += n
266 296
 		if err != nil {
267 297
 			return written, err
268 298
 		}
299
+		err = w.WriteByte('"')
300
+		written++
301
+		if err != nil {
302
+			return written, err
303
+		}
269 304
 		separator = ','
270 305
 	}
271 306
 	if additionalLabelName != "" {
272
-		n, err := fmt.Fprintf(
273
-			out, `%c%s="%s"`,
274
-			separator, additionalLabelName,
275
-			escapeString(additionalLabelValue, true),
276
-		)
307
+		err := w.WriteByte(separator)
308
+		written++
309
+		if err != nil {
310
+			return written, err
311
+		}
312
+		n, err := w.WriteString(additionalLabelName)
313
+		written += n
314
+		if err != nil {
315
+			return written, err
316
+		}
317
+		n, err = w.WriteString(`="`)
318
+		written += n
319
+		if err != nil {
320
+			return written, err
321
+		}
322
+		n, err = writeFloat(w, additionalLabelValue)
277 323
 		written += n
278 324
 		if err != nil {
279 325
 			return written, err
280 326
 		}
327
+		err = w.WriteByte('"')
328
+		written++
329
+		if err != nil {
330
+			return written, err
331
+		}
281 332
 	}
282
-	n, err := out.Write([]byte{'}'})
283
-	written += n
333
+	err := w.WriteByte('}')
334
+	written++
284 335
 	if err != nil {
285 336
 		return written, err
286 337
 	}
287 338
 	return written, nil
288 339
 }
289 340
 
341
+// writeEscapedString replaces '\' by '\\', new line character by '\n', and - if
342
+// includeDoubleQuote is true - '"' by '\"'.
290 343
 var (
291
-	escape                = strings.NewReplacer("\\", `\\`, "\n", `\n`)
292
-	escapeWithDoubleQuote = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`)
344
+	escaper       = strings.NewReplacer("\\", `\\`, "\n", `\n`)
345
+	quotedEscaper = strings.NewReplacer("\\", `\\`, "\n", `\n`, "\"", `\"`)
293 346
 )
294 347
 
295
-// escapeString replaces '\' by '\\', new line character by '\n', and - if
296
-// includeDoubleQuote is true - '"' by '\"'.
297
-func escapeString(v string, includeDoubleQuote bool) string {
348
+func writeEscapedString(w enhancedWriter, v string, includeDoubleQuote bool) (int, error) {
298 349
 	if includeDoubleQuote {
299
-		return escapeWithDoubleQuote.Replace(v)
350
+		return quotedEscaper.WriteString(w, v)
351
+	} else {
352
+		return escaper.WriteString(w, v)
353
+	}
354
+}
355
+
356
+// writeFloat is equivalent to fmt.Fprint with a float64 argument but hardcodes
357
+// a few common cases for increased efficiency. For non-hardcoded cases, it uses
358
+// strconv.AppendFloat to avoid allocations, similar to writeInt.
359
+func writeFloat(w enhancedWriter, f float64) (int, error) {
360
+	switch {
361
+	case f == 1:
362
+		return 1, w.WriteByte('1')
363
+	case f == 0:
364
+		return 1, w.WriteByte('0')
365
+	case f == -1:
366
+		return w.WriteString("-1")
367
+	case math.IsNaN(f):
368
+		return w.WriteString("NaN")
369
+	case math.IsInf(f, +1):
370
+		return w.WriteString("+Inf")
371
+	case math.IsInf(f, -1):
372
+		return w.WriteString("-Inf")
373
+	default:
374
+		bp := numBufPool.Get().(*[]byte)
375
+		*bp = strconv.AppendFloat((*bp)[:0], f, 'g', -1, 64)
376
+		written, err := w.Write(*bp)
377
+		numBufPool.Put(bp)
378
+		return written, err
300 379
 	}
380
+}
301 381
 
302
-	return escape.Replace(v)
382
+// writeInt is equivalent to fmt.Fprint with an int64 argument but uses
383
+// strconv.AppendInt with a byte slice taken from a sync.Pool to avoid
384
+// allocations.
385
+func writeInt(w enhancedWriter, i int64) (int, error) {
386
+	bp := numBufPool.Get().(*[]byte)
387
+	*bp = strconv.AppendInt((*bp)[:0], i, 10)
388
+	written, err := w.Write(*bp)
389
+	numBufPool.Put(bp)
390
+	return written, err
303 391
 }
... ...
@@ -325,7 +325,7 @@ func (p *TextParser) startLabelValue() stateFn {
325 325
 	// - Other labels have to be added to currentLabels for signature calculation.
326 326
 	if p.currentMF.GetType() == dto.MetricType_SUMMARY {
327 327
 		if p.currentLabelPair.GetName() == model.QuantileLabel {
328
-			if p.currentQuantile, p.err = strconv.ParseFloat(p.currentLabelPair.GetValue(), 64); p.err != nil {
328
+			if p.currentQuantile, p.err = parseFloat(p.currentLabelPair.GetValue()); p.err != nil {
329 329
 				// Create a more helpful error message.
330 330
 				p.parseError(fmt.Sprintf("expected float as value for 'quantile' label, got %q", p.currentLabelPair.GetValue()))
331 331
 				return nil
... ...
@@ -337,7 +337,7 @@ func (p *TextParser) startLabelValue() stateFn {
337 337
 	// Similar special treatment of histograms.
338 338
 	if p.currentMF.GetType() == dto.MetricType_HISTOGRAM {
339 339
 		if p.currentLabelPair.GetName() == model.BucketLabel {
340
-			if p.currentBucket, p.err = strconv.ParseFloat(p.currentLabelPair.GetValue(), 64); p.err != nil {
340
+			if p.currentBucket, p.err = parseFloat(p.currentLabelPair.GetValue()); p.err != nil {
341 341
 				// Create a more helpful error message.
342 342
 				p.parseError(fmt.Sprintf("expected float as value for 'le' label, got %q", p.currentLabelPair.GetValue()))
343 343
 				return nil
... ...
@@ -359,7 +359,7 @@ func (p *TextParser) startLabelValue() stateFn {
359 359
 		}
360 360
 		return p.readingValue
361 361
 	default:
362
-		p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.Value))
362
+		p.parseError(fmt.Sprintf("unexpected end of label value %q", p.currentLabelPair.GetValue()))
363 363
 		return nil
364 364
 	}
365 365
 }
... ...
@@ -392,7 +392,7 @@ func (p *TextParser) readingValue() stateFn {
392 392
 	if p.readTokenUntilWhitespace(); p.err != nil {
393 393
 		return nil // Unexpected end of input.
394 394
 	}
395
-	value, err := strconv.ParseFloat(p.currentToken.String(), 64)
395
+	value, err := parseFloat(p.currentToken.String())
396 396
 	if err != nil {
397 397
 		// Create a more helpful error message.
398 398
 		p.parseError(fmt.Sprintf("expected float as value, got %q", p.currentToken.String()))
... ...
@@ -755,3 +755,10 @@ func histogramMetricName(name string) string {
755 755
 		return name
756 756
 	}
757 757
 }
758
+
759
+func parseFloat(s string) (float64, error) {
760
+	if strings.ContainsAny(s, "pP_") {
761
+		return 0, fmt.Errorf("unsupported character in float")
762
+	}
763
+	return strconv.ParseFloat(s, 64)
764
+}
758 765
new file mode 100644
... ...
@@ -0,0 +1,22 @@
0
+module github.com/prometheus/common
1
+
2
+require (
3
+	github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
4
+	github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 // indirect
5
+	github.com/go-kit/kit v0.9.0
6
+	github.com/go-logfmt/logfmt v0.4.0 // indirect
7
+	github.com/golang/protobuf v1.3.2
8
+	github.com/julienschmidt/httprouter v1.2.0
9
+	github.com/matttproud/golang_protobuf_extensions v1.0.1
10
+	github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223
11
+	github.com/pkg/errors v0.8.1
12
+	github.com/prometheus/client_golang v1.0.0
13
+	github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90
14
+	github.com/sirupsen/logrus v1.4.2
15
+	golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 // indirect
16
+	golang.org/x/sys v0.0.0-20190422165155-953cdadca894
17
+	gopkg.in/alecthomas/kingpin.v2 v2.2.6
18
+	gopkg.in/yaml.v2 v2.2.2
19
+)
20
+
21
+go 1.11
... ...
@@ -1,12 +1,12 @@
1 1
 /*
2
+Copyright (c) 2011, Open Knowledge Foundation Ltd.
3
+All rights reserved.
4
+
2 5
 HTTP Content-Type Autonegotiation.
3 6
 
4 7
 The functions in this package implement the behaviour specified in
5 8
 http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
6 9
 
7
-Copyright (c) 2011, Open Knowledge Foundation Ltd.
8
-All rights reserved.
9
-
10 10
 Redistribution and use in source and binary forms, with or without
11 11
 modification, are permitted provided that the following conditions are
12 12
 met:
... ...
@@ -21,7 +21,6 @@ import (
21 21
 )
22 22
 
23 23
 var (
24
-	separator = []byte{0}
25 24
 	// MetricNameRE is a regular expression matching valid metric
26 25
 	// names. Note that the IsValidMetricName function performs the same
27 26
 	// check but faster than a match with this regular expression.
... ...
@@ -43,7 +43,7 @@ const (
43 43
 // (1970-01-01 00:00 UTC) excluding leap seconds.
44 44
 type Time int64
45 45
 
46
-// Interval describes and interval between two timestamps.
46
+// Interval describes an interval between two timestamps.
47 47
 type Interval struct {
48 48
 	Start, End Time
49 49
 }
... ...
@@ -150,7 +150,13 @@ func (t *Time) UnmarshalJSON(b []byte) error {
150 150
 			return err
151 151
 		}
152 152
 
153
-		*t = Time(v + va)
153
+		// If the value was something like -0.1 the negative is lost in the
154
+		// parsing because of the leading zero, this ensures that we capture it.
155
+		if len(p[0]) > 0 && p[0][0] == '-' && v+va > 0 {
156
+			*t = Time(v+va) * -1
157
+		} else {
158
+			*t = Time(v + va)
159
+		}
154 160
 
155 161
 	default:
156 162
 		return fmt.Errorf("invalid time %q", string(b))