Skip to content

Releases: takattila/prometheus

Quick fixes

18 Jul 16:38

Choose a tag to compare

Fixed: cpuP.getFirstElement error

In stats.go:

 func (c cpuP) getFirstElement() float64 {
-   if c.err != nil {
+   if c.err != nil || len(c.per) == 0 {
        return float64(0)
    }
    return c.per[0]

Removed: promhttp.HandlerOpts

In common.go:

    r.Handle(o.MetricsEndpoint, promhttp.HandlerFor(
-       o.reg, promhttp.HandlerOpts{
-           DisableCompression:  true,
-           MaxRequestsInFlight: 1,
-           EnableOpenMetrics:   true,
-       }))
+       o.reg, promhttp.HandlerOpts{}))

Added defaultBuckets instead of GenerateBuckets(0.5, 0.5, 20)

In histogram.go:

+var defaultBuckets = []float64{
+   0.000025, 0.00005, 0.0025, 0.005, 0.025, 0.05,
+   0.1, 0.25, 0.5, 1, 2.5, 5, 10, 20, 25, 50, 60, 120,
+}
+
func GenerateBuckets(start, width float64, count int) []float64 {
 
 func makeLinearBuckets(buckets []float64) []float64 {
    if len(buckets) == 0 {
-       return GenerateBuckets(0.5, 0.5, 20)
+       return defaultBuckets
    }
    return buckets
 }

Renamed: Units to Buckets

04 Jul 19:29

Choose a tag to compare

Renamed GenerateUnits to GenerateBuckets

-// GenerateUnits creates a float64 slice to measure request durations.
-func GenerateUnits(start, width float64, count int) []float64 {

+// GenerateBuckets creates a float64 slice to measure request durations.
+func GenerateBuckets(start, width float64, count int) []float64 {

Using Buckets instead of Units

... in HistogramArgs

 type HistogramArgs struct {
    MetricName string
    Labels     Labels
-   Units      []float64
+   Buckets    []float64
    Value      float64
 }

... in MeasureExecTime

type MeasureExecTime struct {
    MetricName   string
    Labels       Labels
-   Units        []float64
+   Buckets      []float64
    TimeDuration time.Duration
 
    object *Object
    start  time.Time
}

Added argument structures as a parameter to metric functions

03 Jul 18:02

Choose a tag to compare

Argument structures as a parameter

Counter

err := p.Counter(prometheus.CounterArgs{
    MetricName: "response_status",
    Labels:     prometheus.Labels{"handler": "MyHandler1", "statuscode": "200"},
    Value:      1,
})

if err != nil {
    log.Fatal(err)
}

fmt.Println(p.GetMetrics("response_status"))

Gauge

err := p.Gauge(prometheus.GaugeArgs{
    MetricName: "cpu_usage_example",
    Labels:     prometheus.Labels{"core": "0"},
    Value:      float64(rand.Intn(100)),
})

if err != nil {
    log.Fatal(err)
}

fmt.Println(p.GetMetrics("cpu_usage_example"))

Histogram

// Elapsed time to measure the computation time
// of a given function, handler, etc...
defer func(begin time.Time) {
    err := p.Histogram(prometheus.HistogramArgs{
        MetricName: "elapsed_time",
        Labels:     prometheus.Labels{"handler": "MyHandler2"},
        Units:      prometheus.GenerateUnits(0.05, 0.05, 10),
        Value:      time.Since(begin).Seconds(),
    })

	if err != nil {
		log.Fatal(err)
	}
}(time.Now())

Pprof handlers can be turned on/off on initialization

p := prometheus.New(prometheus.Init{
    // Obligatory fields
    Host:        "0.0.0.0",
    Port:        prometheus.GetFreePort(),
    Environment: "test",
    AppName:     "ExampleService",

    // Endpoint: /debug/pprof/
    EnablePprof: true, // default: false, 
})

Measure execution time function

02 Jul 14:10

Choose a tag to compare

Measure execution time

To measure the runtime of a particular calculation use StartMeasureExecTime function.

Example code

p := prometheus.New(prometheus.Init{
    // Obligatory fields
    Host:        "0.0.0.0",
    Port:        prometheus.GetFreePort(),
    Environment: "test",
    AppName:     "ExampleApp",
})

ms := p.StartMeasureExecTime(prometheus.MeasureExecTime{
    MetricName:   "execution_time_milli_sec",
    Labels:       prometheus.Labels{"function": "calculate"},
    Units:        prometheus.GenerateUnits(5, 5, 10),
    TimeDuration: time.Millisecond,
})

time.Sleep(10 * time.Millisecond)

err := ms.StopMeasureExecTime()
if err != nil {
    log.Fatal(err)
}

fmt.Println(p.GetMetrics("execution_time_milli_sec"))

Example output

# HELP execution_time_milli_sec Histogram created for execution_time_milli_sec
# TYPE execution_time_milli_sec histogram
execution_time_milli_sec_bucket{app="ExampleApp",env="test",function="calculate",le="5"} 0
execution_time_milli_sec_bucket{app="ExampleApp",env="test",function="calculate",le="10"} 1
execution_time_milli_sec_bucket{app="ExampleApp",env="test",function="calculate",le="15"} 1
execution_time_milli_sec_bucket{app="ExampleApp",env="test",function="calculate",le="20"} 1
execution_time_milli_sec_bucket{app="ExampleApp",env="test",function="calculate",le="25"} 1
execution_time_milli_sec_bucket{app="ExampleApp",env="test",function="calculate",le="30"} 1
execution_time_milli_sec_bucket{app="ExampleApp",env="test",function="calculate",le="35"} 1
execution_time_milli_sec_bucket{app="ExampleApp",env="test",function="calculate",le="40"} 1
execution_time_milli_sec_bucket{app="ExampleApp",env="test",function="calculate",le="45"} 1
execution_time_milli_sec_bucket{app="ExampleApp",env="test",function="calculate",le="50"} 1
execution_time_milli_sec_bucket{app="ExampleApp",env="test",function="calculate",le="+Inf"} 1
execution_time_milli_sec_sum{app="ExampleApp",env="test",function="calculate"} 10
execution_time_milli_sec_count{app="ExampleApp",env="test",function="calculate"} 1

GenerateUnits function with specified decimal places

01 Jul 18:21

Choose a tag to compare

GenerateUnits

The length of the decimal places of the generated float64 numbers are fixed: depends on the number of decimal places of "start" and "width" arguments.

Example

units := prometheus.GenerateUnits(1, 1.5, 8)
fmt.Println(units)

units = prometheus.GenerateUnits(2.5, 2, 10)
fmt.Println(units)

units = prometheus.GenerateUnits(0.5, 0.55, 10)
fmt.Println(units)

Output

[1 2.5 4 5.5 7 8.5 10 11.5]
[2.5 4.5 6.5 8.5 10.5 12.5 14.5 16.5 18.5 20.5]
[0.5 1.05 1.6 2.15 2.7 3.25 3.8 4.35 4.9 5.45]

RoundFloat

Example

float := prometheus.RoundFloat(1.559633154856, 2)
fmt.Println(float)

Output

1.56

DecimalPlaces

Example

dp := prometheus.DecimalPlaces(1.554)
fmt.Println(dp)

Output

3

Removed ElapsedTime function use Histogram instead

22 Jun 18:24

Choose a tag to compare

Elapsed time

Here is an example, how to use Histogram instead of ElapsedTime function:

p := prometheus.New(prometheus.Init{
	Host:        "0.0.0.0",
	Port:        prometheus.GetFreePort(),
	Environment: "test",
	AppName:     "ExampleHistogram",
})

start := time.Now()

// Elapsed time to measure the computation time
// of a given function, handler, etc...
defer func(begin time.Time) {
	units := prometheus.GenerateUnits(0.05, 0.05, 5)
	since := time.Since(begin).Seconds()

	err := p.Histogram("get_stat", since, prometheus.Labels{
		"handler": "purchases",
	}, units...)

	if err != nil {
		log.Fatal(err)
	}
}(start)

time.Sleep(100 * time.Millisecond)

// Output example:
// # HELP get_stat Histogram created for get_stat
// # TYPE get_stat histogram
// get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="0.05"} 0
// get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="0.1"} 0
// get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="0.15000000000000002"} 1
// get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="0.2"} 1
// get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="0.25"} 1
// get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="+Inf"} 1
// get_stat_sum{app="ExampleElapsedTime",env="test",handler="purchases"} 0.100132995
// get_stat_count{app="ExampleElapsedTime",env="test",handler="purchases"} 1

Initialized package

21 Jun 21:25

Choose a tag to compare

Initialization

Example code

p := prometheus.New(prometheus.Init{
    // Obligatory fields
    Host:        "0.0.0.0",
    Port:        prometheus.GetFreePort(),
    Environment: "test",
    AppName:     "ExampleService",

    // Optional fields
    MetricEndpoint:      "/metrics", // default: /metrics
    StatCountGoroutines: true,       // default: false
    StatMemoryUsage:     true,       // default: false
    StatCpuUsage:        true,       // default: false
})

Example output

{
  "Addr": "0.0.0.0:40045",
  "Env": "test",
  "App": "ExampleService",
  "MetricsEndpoint": "/metrics",
  "StatCountGoroutines": true,
  "StatMemoryUsage": true,
  "StatCpuUsage": true
}

Counter

Counter is a cumulative metric that represents a single monotonically increasing counter
whose value can only increase or be reset to zero on restart.

For example, you can use a counter to represent the number
of requests served, tasks completed, or errors.

Example code

err := p.Counter("response_status", 1, prometheus.Labels{
    "handler":    "MyHandler1",
    "statuscode": "200",
})

fmt.Println(p.GetMetrics("response_status"))

Example output

# HELP response_status Counter created for response_status
# TYPE response_status counter
response_status{app="ExampleCounter",env="test",handler="MyHandler1",statuscode="200"} 1

Gauge

Gauge is a metric that represents a single numerical value
that can arbitrarily go up and down.

Gauges are typically used for measured values like temperatures
or current memory usage, but also "counts" that can go up and down,
like the number of concurrent requests.

Example code

err := p.Gauge("cpu_usage_example", 15, prometheus.Labels{
    "core": "0",
})

fmt.Println(p.GetMetrics("cpu_usage"))

Example output

# HELP cpu_usage Gauge created for cpu_usage
# TYPE cpu_usage gauge
cpu_usage{app="ExampleGauge",core="0",env="test"} 15

Histogram

Histogram samples observations (usually things like request durations
or response sizes) and counts them in configurable buckets.
It also provides a sum of all observed values.
A histogram with a base metric name of
exposes multiple time series during a scrape:

  • cumulative counters for the observation buckets, exposed
    as _bucket{le=""}
  • the total sum of all observed values, exposed as _sum
  • the count of events that have been observed, exposed
    as _count (identical to _bucket{le="+Inf"} above)

Example code

since := time.Since(time.Now()).Seconds()
units := prometheus.GenerateUnits(1, 1, 5)

err := p.Histogram("history", since, prometheus.Labels{
    "sell": "actual",
}, units...)

fmt.Println()
fmt.Println(p.GetMetrics("history_bucket"))

Example output

history_bucket{app="ExampleHistogram",env="test",sell="actual",le="1"} 1
history_bucket{app="ExampleHistogram",env="test",sell="actual",le="2"} 1
history_bucket{app="ExampleHistogram",env="test",sell="actual",le="3"} 1
history_bucket{app="ExampleHistogram",env="test",sell="actual",le="4"} 1
history_bucket{app="ExampleHistogram",env="test",sell="actual",le="5"} 1
history_bucket{app="ExampleHistogram",env="test",sell="actual",le="+Inf"} 1

Elapsed time

Place this code bellow to measure the computation time of a given function, handler, etc.

Example code

start := time.Now()

defer func(begin time.Time) {
    units := prometheus.GenerateUnits(0.05, 0.05, 5)

    err := p.ElapsedTime("get_stat", begin, prometheus.Labels{
        "handler": "purchases",
    }, units...)

    if err != nil {
        log.Fatal(err)
    }
}(start)

time.Sleep(100 * time.Millisecond)

Example output

# HELP get_stat Histogram created for get_stat
# TYPE get_stat histogram
get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="0.05"} 0
get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="0.1"} 0
get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="0.15000000000000002"} 1
get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="0.2"} 1
get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="0.25"} 1
get_stat_bucket{app="ExampleElapsedTime",env="test",handler="purchases",le="+Inf"} 1
get_stat_sum{app="ExampleElapsedTime",env="test",handler="purchases"} 0.100132995
get_stat_count{app="ExampleElapsedTime",env="test",handler="purchases"} 1