Source file src/runtime/metrics/example_test.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package metrics_test
     6  
     7  import (
     8  	"fmt"
     9  	"runtime/metrics"
    10  )
    11  
    12  func ExampleRead_readingOneMetric() {
    13  	// Name of the metric we want to read.
    14  	const myMetric = "/memory/classes/heap/free:bytes"
    15  
    16  	// Create a sample for the metric.
    17  	sample := make([]metrics.Sample, 1)
    18  	sample[0].Name = myMetric
    19  
    20  	// Sample the metric.
    21  	metrics.Read(sample)
    22  
    23  	// Check if the metric is actually supported.
    24  	// If it's not, the resulting value will always have
    25  	// kind KindBad.
    26  	if sample[0].Value.Kind() == metrics.KindBad {
    27  		panic(fmt.Sprintf("metric %q no longer supported", myMetric))
    28  	}
    29  
    30  	// Handle the result.
    31  	//
    32  	// It's OK to assume a particular Kind for a metric;
    33  	// they're guaranteed not to change.
    34  	freeBytes := sample[0].Value.Uint64()
    35  
    36  	fmt.Printf("free but not released memory: %d\n", freeBytes)
    37  }
    38  
    39  func ExampleRead_readingAllMetrics() {
    40  	// Get descriptions for all supported metrics.
    41  	descs := metrics.All()
    42  
    43  	// Create a sample for each metric.
    44  	samples := make([]metrics.Sample, len(descs))
    45  	for i := range samples {
    46  		samples[i].Name = descs[i].Name
    47  	}
    48  
    49  	// Sample the metrics. Re-use the samples slice if you can!
    50  	metrics.Read(samples)
    51  
    52  	// Iterate over all results.
    53  	for _, sample := range samples {
    54  		// Pull out the name and value.
    55  		name, value := sample.Name, sample.Value
    56  
    57  		// Handle each sample.
    58  		switch value.Kind() {
    59  		case metrics.KindUint64:
    60  			fmt.Printf("%s: %d\n", name, value.Uint64())
    61  		case metrics.KindFloat64:
    62  			fmt.Printf("%s: %f\n", name, value.Float64())
    63  		case metrics.KindFloat64Histogram:
    64  			// The histogram may be quite large, so let's just pull out
    65  			// a crude estimate for the median for the sake of this example.
    66  			fmt.Printf("%s: %f\n", name, medianBucket(value.Float64Histogram()))
    67  		case metrics.KindBad:
    68  			// This should never happen because all metrics are supported
    69  			// by construction.
    70  			panic("bug in runtime/metrics package!")
    71  		default:
    72  			// This may happen as new metrics get added.
    73  			//
    74  			// The safest thing to do here is to simply log it somewhere
    75  			// as something to look into, but ignore it for now.
    76  			// In the worst case, you might temporarily miss out on a new metric.
    77  			fmt.Printf("%s: unexpected metric Kind: %v\n", name, value.Kind())
    78  		}
    79  	}
    80  }
    81  
    82  func medianBucket(h *metrics.Float64Histogram) float64 {
    83  	total := uint64(0)
    84  	for _, count := range h.Counts {
    85  		total += count
    86  	}
    87  	thresh := total / 2
    88  	total = 0
    89  	for i, count := range h.Counts {
    90  		total += count
    91  		if total >= thresh {
    92  			return h.Buckets[i]
    93  		}
    94  	}
    95  	panic("should not happen")
    96  }
    97  

View as plain text