...

Source file src/go.opencensus.io/plugin/runmetrics/producer.go

Documentation: go.opencensus.io/plugin/runmetrics

     1  package runmetrics
     2  
     3  import (
     4  	"errors"
     5  	"runtime"
     6  	"sync"
     7  	"time"
     8  
     9  	"go.opencensus.io/metric"
    10  	"go.opencensus.io/metric/metricdata"
    11  	"go.opencensus.io/metric/metricproducer"
    12  )
    13  
    14  type (
    15  	// producer produces runtime metrics.
    16  	//
    17  	// Enable collection of runtime metrics with Enable().
    18  	producer struct {
    19  		options RunMetricOptions
    20  		reg     *metric.Registry
    21  
    22  		deprecatedMemStats *deprecatedMemStats
    23  		memStats           *memStats
    24  		cpuStats           *cpuStats
    25  	}
    26  
    27  	// RunMetricOptions allows to configure runtime metrics.
    28  	RunMetricOptions struct {
    29  		EnableCPU            bool   // EnableCPU whether CPU metrics shall be recorded
    30  		EnableMemory         bool   // EnableMemory whether memory metrics shall be recorded
    31  		Prefix               string // Prefix is a custom prefix for metric names
    32  		UseDerivedCumulative bool   // UseDerivedCumulative whether DerivedCumulative metrics should be used
    33  	}
    34  
    35  	deprecatedMemStats struct {
    36  		memStats runtime.MemStats
    37  
    38  		memAlloc   *metric.Int64GaugeEntry
    39  		memTotal   *metric.Int64GaugeEntry
    40  		memSys     *metric.Int64GaugeEntry
    41  		memLookups *metric.Int64GaugeEntry
    42  		memMalloc  *metric.Int64GaugeEntry
    43  		memFrees   *metric.Int64GaugeEntry
    44  
    45  		heapAlloc    *metric.Int64GaugeEntry
    46  		heapSys      *metric.Int64GaugeEntry
    47  		heapIdle     *metric.Int64GaugeEntry
    48  		heapInuse    *metric.Int64GaugeEntry
    49  		heapObjects  *metric.Int64GaugeEntry
    50  		heapReleased *metric.Int64GaugeEntry
    51  
    52  		stackInuse       *metric.Int64GaugeEntry
    53  		stackSys         *metric.Int64GaugeEntry
    54  		stackMSpanInuse  *metric.Int64GaugeEntry
    55  		stackMSpanSys    *metric.Int64GaugeEntry
    56  		stackMCacheInuse *metric.Int64GaugeEntry
    57  		stackMCacheSys   *metric.Int64GaugeEntry
    58  
    59  		otherSys      *metric.Int64GaugeEntry
    60  		gcSys         *metric.Int64GaugeEntry
    61  		numGC         *metric.Int64GaugeEntry
    62  		numForcedGC   *metric.Int64GaugeEntry
    63  		nextGC        *metric.Int64GaugeEntry
    64  		lastGC        *metric.Int64GaugeEntry
    65  		pauseTotalNs  *metric.Int64GaugeEntry
    66  		gcCPUFraction *metric.Float64Entry
    67  	}
    68  
    69  	memStats struct {
    70  		memStats runtime.MemStats
    71  
    72  		memAlloc   *metric.Int64GaugeEntry
    73  		memTotal   *metric.Int64DerivedCumulative
    74  		memSys     *metric.Int64GaugeEntry
    75  		memLookups *metric.Int64DerivedCumulative
    76  		memMalloc  *metric.Int64DerivedCumulative
    77  		memFrees   *metric.Int64DerivedCumulative
    78  
    79  		heapAlloc    *metric.Int64GaugeEntry
    80  		heapSys      *metric.Int64GaugeEntry
    81  		heapIdle     *metric.Int64GaugeEntry
    82  		heapInuse    *metric.Int64GaugeEntry
    83  		heapObjects  *metric.Int64GaugeEntry
    84  		heapReleased *metric.Int64DerivedCumulative
    85  
    86  		stackInuse       *metric.Int64GaugeEntry
    87  		stackSys         *metric.Int64GaugeEntry
    88  		stackMSpanInuse  *metric.Int64GaugeEntry
    89  		stackMSpanSys    *metric.Int64GaugeEntry
    90  		stackMCacheInuse *metric.Int64GaugeEntry
    91  		stackMCacheSys   *metric.Int64GaugeEntry
    92  
    93  		otherSys      *metric.Int64GaugeEntry
    94  		gcSys         *metric.Int64GaugeEntry
    95  		numGC         *metric.Int64DerivedCumulative
    96  		numForcedGC   *metric.Int64DerivedCumulative
    97  		nextGC        *metric.Int64GaugeEntry
    98  		lastGC        *metric.Int64GaugeEntry
    99  		pauseTotalNs  *metric.Int64DerivedCumulative
   100  		gcCPUFraction *metric.Float64Entry
   101  	}
   102  
   103  	cpuStats struct {
   104  		numGoroutines *metric.Int64GaugeEntry
   105  		numCgoCalls   *metric.Int64GaugeEntry
   106  	}
   107  )
   108  
   109  var (
   110  	_               metricproducer.Producer = (*producer)(nil)
   111  	enableMutex     sync.Mutex
   112  	enabledProducer *producer
   113  )
   114  
   115  // Enable enables collection of runtime metrics.
   116  //
   117  // Supply RunMetricOptions to configure the behavior of metrics collection.
   118  // An error might be returned, if creating metrics gauges fails.
   119  //
   120  // Previous calls will be overwritten by subsequent ones.
   121  func Enable(options RunMetricOptions) error {
   122  	producer := &producer{options: options, reg: metric.NewRegistry()}
   123  	var err error
   124  
   125  	if options.EnableMemory {
   126  		switch options.UseDerivedCumulative {
   127  		case true:
   128  			producer.memStats, err = newMemStats(producer)
   129  			if err != nil {
   130  				return err
   131  			}
   132  		default:
   133  			producer.deprecatedMemStats, err = newDeprecatedMemStats(producer)
   134  			if err != nil {
   135  				return err
   136  			}
   137  		}
   138  	}
   139  
   140  	if options.EnableCPU {
   141  		producer.cpuStats, err = newCPUStats(producer)
   142  		if err != nil {
   143  			return err
   144  		}
   145  	}
   146  
   147  	enableMutex.Lock()
   148  	defer enableMutex.Unlock()
   149  
   150  	metricproducer.GlobalManager().DeleteProducer(enabledProducer)
   151  	metricproducer.GlobalManager().AddProducer(producer)
   152  	enabledProducer = producer
   153  
   154  	return nil
   155  }
   156  
   157  // Disable disables collection of runtime metrics.
   158  func Disable() {
   159  	enableMutex.Lock()
   160  	defer enableMutex.Unlock()
   161  
   162  	metricproducer.GlobalManager().DeleteProducer(enabledProducer)
   163  	enabledProducer = nil
   164  }
   165  
   166  // Read reads the current runtime metrics.
   167  func (p *producer) Read() []*metricdata.Metric {
   168  	if p.memStats != nil {
   169  		p.memStats.read()
   170  	}
   171  
   172  	if p.cpuStats != nil {
   173  		p.cpuStats.read()
   174  	}
   175  
   176  	return p.reg.Read()
   177  }
   178  
   179  func newDeprecatedMemStats(producer *producer) (*deprecatedMemStats, error) {
   180  	var err error
   181  	memStats := &deprecatedMemStats{}
   182  
   183  	// General
   184  	memStats.memAlloc, err = producer.createInt64GaugeEntry("process/memory_alloc", "Number of bytes currently allocated in use", metricdata.UnitBytes)
   185  	if err != nil {
   186  		return nil, err
   187  	}
   188  
   189  	memStats.memTotal, err = producer.createInt64GaugeEntry("process/total_memory_alloc", "Number of allocations in total", metricdata.UnitBytes)
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  
   194  	memStats.memSys, err = producer.createInt64GaugeEntry("process/sys_memory_alloc", "Number of bytes given to the process to use in total", metricdata.UnitBytes)
   195  	if err != nil {
   196  		return nil, err
   197  	}
   198  
   199  	memStats.memLookups, err = producer.createInt64GaugeEntry("process/memory_lookups", "Cumulative number of pointer lookups performed by the runtime", metricdata.UnitDimensionless)
   200  	if err != nil {
   201  		return nil, err
   202  	}
   203  
   204  	memStats.memMalloc, err = producer.createInt64GaugeEntry("process/memory_malloc", "Cumulative count of heap objects allocated", metricdata.UnitDimensionless)
   205  	if err != nil {
   206  		return nil, err
   207  	}
   208  
   209  	memStats.memFrees, err = producer.createInt64GaugeEntry("process/memory_frees", "Cumulative count of heap objects freed", metricdata.UnitDimensionless)
   210  	if err != nil {
   211  		return nil, err
   212  	}
   213  
   214  	// Heap
   215  	memStats.heapAlloc, err = producer.createInt64GaugeEntry("process/heap_alloc", "Process heap allocation", metricdata.UnitBytes)
   216  	if err != nil {
   217  		return nil, err
   218  	}
   219  
   220  	memStats.heapSys, err = producer.createInt64GaugeEntry("process/sys_heap", "Bytes of heap memory obtained from the OS", metricdata.UnitBytes)
   221  	if err != nil {
   222  		return nil, err
   223  	}
   224  
   225  	memStats.heapIdle, err = producer.createInt64GaugeEntry("process/heap_idle", "Bytes in idle (unused) spans", metricdata.UnitBytes)
   226  	if err != nil {
   227  		return nil, err
   228  	}
   229  
   230  	memStats.heapInuse, err = producer.createInt64GaugeEntry("process/heap_inuse", "Bytes in in-use spans", metricdata.UnitBytes)
   231  	if err != nil {
   232  		return nil, err
   233  	}
   234  
   235  	memStats.heapObjects, err = producer.createInt64GaugeEntry("process/heap_objects", "The number of objects allocated on the heap", metricdata.UnitDimensionless)
   236  	if err != nil {
   237  		return nil, err
   238  	}
   239  
   240  	memStats.heapReleased, err = producer.createInt64GaugeEntry("process/heap_release", "The cumulative number of objects released from the heap", metricdata.UnitBytes)
   241  	if err != nil {
   242  		return nil, err
   243  	}
   244  
   245  	// Stack
   246  	memStats.stackInuse, err = producer.createInt64GaugeEntry("process/stack_inuse", "Bytes in stack spans", metricdata.UnitBytes)
   247  	if err != nil {
   248  		return nil, err
   249  	}
   250  
   251  	memStats.stackSys, err = producer.createInt64GaugeEntry("process/sys_stack", "The memory used by stack spans and OS thread stacks", metricdata.UnitBytes)
   252  	if err != nil {
   253  		return nil, err
   254  	}
   255  
   256  	memStats.stackMSpanInuse, err = producer.createInt64GaugeEntry("process/stack_mspan_inuse", "Bytes of allocated mspan structures", metricdata.UnitBytes)
   257  	if err != nil {
   258  		return nil, err
   259  	}
   260  
   261  	memStats.stackMSpanSys, err = producer.createInt64GaugeEntry("process/sys_stack_mspan", "Bytes of memory obtained from the OS for mspan structures", metricdata.UnitBytes)
   262  	if err != nil {
   263  		return nil, err
   264  	}
   265  
   266  	memStats.stackMCacheInuse, err = producer.createInt64GaugeEntry("process/stack_mcache_inuse", "Bytes of allocated mcache structures", metricdata.UnitBytes)
   267  	if err != nil {
   268  		return nil, err
   269  	}
   270  
   271  	memStats.stackMCacheSys, err = producer.createInt64GaugeEntry("process/sys_stack_mcache", "Bytes of memory obtained from the OS for mcache structures", metricdata.UnitBytes)
   272  	if err != nil {
   273  		return nil, err
   274  	}
   275  
   276  	// GC
   277  	memStats.gcSys, err = producer.createInt64GaugeEntry("process/gc_sys", "Bytes of memory in garbage collection metadatas", metricdata.UnitBytes)
   278  	if err != nil {
   279  		return nil, err
   280  	}
   281  
   282  	memStats.otherSys, err = producer.createInt64GaugeEntry("process/other_sys", "Bytes of memory in miscellaneous off-heap runtime allocations", metricdata.UnitBytes)
   283  	if err != nil {
   284  		return nil, err
   285  	}
   286  
   287  	memStats.numGC, err = producer.createInt64GaugeEntry("process/num_gc", "Cumulative count of completed GC cycles", metricdata.UnitDimensionless)
   288  	if err != nil {
   289  		return nil, err
   290  	}
   291  
   292  	memStats.numForcedGC, err = producer.createInt64GaugeEntry("process/num_forced_gc", "Cumulative count of GC cycles forced by the application", metricdata.UnitDimensionless)
   293  	if err != nil {
   294  		return nil, err
   295  	}
   296  
   297  	memStats.nextGC, err = producer.createInt64GaugeEntry("process/next_gc_heap_size", "Target heap size of the next GC cycle in bytes", metricdata.UnitBytes)
   298  	if err != nil {
   299  		return nil, err
   300  	}
   301  
   302  	memStats.lastGC, err = producer.createInt64GaugeEntry("process/last_gc_finished_timestamp", "Time the last garbage collection finished, as milliseconds since 1970 (the UNIX epoch)", metricdata.UnitMilliseconds)
   303  	if err != nil {
   304  		return nil, err
   305  	}
   306  
   307  	memStats.pauseTotalNs, err = producer.createInt64GaugeEntry("process/pause_total", "Cumulative milliseconds spent in GC stop-the-world pauses", metricdata.UnitMilliseconds)
   308  	if err != nil {
   309  		return nil, err
   310  	}
   311  
   312  	memStats.gcCPUFraction, err = producer.createFloat64GaugeEntry("process/gc_cpu_fraction", "Fraction of this program's available CPU time used by the GC since the program started", metricdata.UnitDimensionless)
   313  	if err != nil {
   314  		return nil, err
   315  	}
   316  
   317  	return memStats, nil
   318  }
   319  
   320  func (m *deprecatedMemStats) read() {
   321  	runtime.ReadMemStats(&m.memStats)
   322  
   323  	m.memAlloc.Set(int64(m.memStats.Alloc))
   324  	m.memTotal.Set(int64(m.memStats.TotalAlloc))
   325  	m.memSys.Set(int64(m.memStats.Sys))
   326  	m.memLookups.Set(int64(m.memStats.Lookups))
   327  	m.memMalloc.Set(int64(m.memStats.Mallocs))
   328  	m.memFrees.Set(int64(m.memStats.Frees))
   329  
   330  	m.heapAlloc.Set(int64(m.memStats.HeapAlloc))
   331  	m.heapSys.Set(int64(m.memStats.HeapSys))
   332  	m.heapIdle.Set(int64(m.memStats.HeapIdle))
   333  	m.heapInuse.Set(int64(m.memStats.HeapInuse))
   334  	m.heapReleased.Set(int64(m.memStats.HeapReleased))
   335  	m.heapObjects.Set(int64(m.memStats.HeapObjects))
   336  
   337  	m.stackInuse.Set(int64(m.memStats.StackInuse))
   338  	m.stackSys.Set(int64(m.memStats.StackSys))
   339  	m.stackMSpanInuse.Set(int64(m.memStats.MSpanInuse))
   340  	m.stackMSpanSys.Set(int64(m.memStats.MSpanSys))
   341  	m.stackMCacheInuse.Set(int64(m.memStats.MCacheInuse))
   342  	m.stackMCacheSys.Set(int64(m.memStats.MCacheSys))
   343  
   344  	m.gcSys.Set(int64(m.memStats.GCSys))
   345  	m.otherSys.Set(int64(m.memStats.OtherSys))
   346  	m.numGC.Set(int64(m.memStats.NumGC))
   347  	m.numForcedGC.Set(int64(m.memStats.NumForcedGC))
   348  	m.nextGC.Set(int64(m.memStats.NextGC))
   349  	m.lastGC.Set(int64(m.memStats.LastGC) / int64(time.Millisecond))
   350  	m.pauseTotalNs.Set(int64(m.memStats.PauseTotalNs) / int64(time.Millisecond))
   351  	m.gcCPUFraction.Set(m.memStats.GCCPUFraction)
   352  }
   353  
   354  func newMemStats(producer *producer) (*memStats, error) {
   355  	var err error
   356  	memStats := &memStats{}
   357  
   358  	// General
   359  	memStats.memAlloc, err = producer.createInt64GaugeEntry("process/memory_alloc", "Number of bytes currently allocated in use", metricdata.UnitBytes)
   360  	if err != nil {
   361  		return nil, err
   362  	}
   363  
   364  	memStats.memTotal, err = producer.createInt64DerivedCumulative("process/total_memory_alloc", "Number of allocations in total", metricdata.UnitBytes)
   365  	if err != nil {
   366  		return nil, err
   367  	}
   368  
   369  	memStats.memSys, err = producer.createInt64GaugeEntry("process/sys_memory_alloc", "Number of bytes given to the process to use in total", metricdata.UnitBytes)
   370  	if err != nil {
   371  		return nil, err
   372  	}
   373  
   374  	memStats.memLookups, err = producer.createInt64DerivedCumulative("process/memory_lookups", "Cumulative number of pointer lookups performed by the runtime", metricdata.UnitDimensionless)
   375  	if err != nil {
   376  		return nil, err
   377  	}
   378  
   379  	memStats.memMalloc, err = producer.createInt64DerivedCumulative("process/memory_malloc", "Cumulative count of heap objects allocated", metricdata.UnitDimensionless)
   380  	if err != nil {
   381  		return nil, err
   382  	}
   383  
   384  	memStats.memFrees, err = producer.createInt64DerivedCumulative("process/memory_frees", "Cumulative count of heap objects freed", metricdata.UnitDimensionless)
   385  	if err != nil {
   386  		return nil, err
   387  	}
   388  
   389  	// Heap
   390  	memStats.heapAlloc, err = producer.createInt64GaugeEntry("process/heap_alloc", "Process heap allocation", metricdata.UnitBytes)
   391  	if err != nil {
   392  		return nil, err
   393  	}
   394  
   395  	memStats.heapSys, err = producer.createInt64GaugeEntry("process/sys_heap", "Bytes of heap memory obtained from the OS", metricdata.UnitBytes)
   396  	if err != nil {
   397  		return nil, err
   398  	}
   399  
   400  	memStats.heapIdle, err = producer.createInt64GaugeEntry("process/heap_idle", "Bytes in idle (unused) spans", metricdata.UnitBytes)
   401  	if err != nil {
   402  		return nil, err
   403  	}
   404  
   405  	memStats.heapInuse, err = producer.createInt64GaugeEntry("process/heap_inuse", "Bytes in in-use spans", metricdata.UnitBytes)
   406  	if err != nil {
   407  		return nil, err
   408  	}
   409  
   410  	memStats.heapObjects, err = producer.createInt64GaugeEntry("process/heap_objects", "The number of objects allocated on the heap", metricdata.UnitDimensionless)
   411  	if err != nil {
   412  		return nil, err
   413  	}
   414  
   415  	memStats.heapReleased, err = producer.createInt64DerivedCumulative("process/heap_release", "The cumulative number of objects released from the heap", metricdata.UnitBytes)
   416  	if err != nil {
   417  		return nil, err
   418  	}
   419  
   420  	// Stack
   421  	memStats.stackInuse, err = producer.createInt64GaugeEntry("process/stack_inuse", "Bytes in stack spans", metricdata.UnitBytes)
   422  	if err != nil {
   423  		return nil, err
   424  	}
   425  
   426  	memStats.stackSys, err = producer.createInt64GaugeEntry("process/sys_stack", "The memory used by stack spans and OS thread stacks", metricdata.UnitBytes)
   427  	if err != nil {
   428  		return nil, err
   429  	}
   430  
   431  	memStats.stackMSpanInuse, err = producer.createInt64GaugeEntry("process/stack_mspan_inuse", "Bytes of allocated mspan structures", metricdata.UnitBytes)
   432  	if err != nil {
   433  		return nil, err
   434  	}
   435  
   436  	memStats.stackMSpanSys, err = producer.createInt64GaugeEntry("process/sys_stack_mspan", "Bytes of memory obtained from the OS for mspan structures", metricdata.UnitBytes)
   437  	if err != nil {
   438  		return nil, err
   439  	}
   440  
   441  	memStats.stackMCacheInuse, err = producer.createInt64GaugeEntry("process/stack_mcache_inuse", "Bytes of allocated mcache structures", metricdata.UnitBytes)
   442  	if err != nil {
   443  		return nil, err
   444  	}
   445  
   446  	memStats.stackMCacheSys, err = producer.createInt64GaugeEntry("process/sys_stack_mcache", "Bytes of memory obtained from the OS for mcache structures", metricdata.UnitBytes)
   447  	if err != nil {
   448  		return nil, err
   449  	}
   450  
   451  	// GC
   452  	memStats.gcSys, err = producer.createInt64GaugeEntry("process/gc_sys", "Bytes of memory in garbage collection metadatas", metricdata.UnitBytes)
   453  	if err != nil {
   454  		return nil, err
   455  	}
   456  
   457  	memStats.otherSys, err = producer.createInt64GaugeEntry("process/other_sys", "Bytes of memory in miscellaneous off-heap runtime allocations", metricdata.UnitBytes)
   458  	if err != nil {
   459  		return nil, err
   460  	}
   461  
   462  	memStats.numGC, err = producer.createInt64DerivedCumulative("process/num_gc", "Cumulative count of completed GC cycles", metricdata.UnitDimensionless)
   463  	if err != nil {
   464  		return nil, err
   465  	}
   466  
   467  	memStats.numForcedGC, err = producer.createInt64DerivedCumulative("process/num_forced_gc", "Cumulative count of GC cycles forced by the application", metricdata.UnitDimensionless)
   468  	if err != nil {
   469  		return nil, err
   470  	}
   471  
   472  	memStats.nextGC, err = producer.createInt64GaugeEntry("process/next_gc_heap_size", "Target heap size of the next GC cycle in bytes", metricdata.UnitBytes)
   473  	if err != nil {
   474  		return nil, err
   475  	}
   476  
   477  	memStats.lastGC, err = producer.createInt64GaugeEntry("process/last_gc_finished_timestamp", "Time the last garbage collection finished, as milliseconds since 1970 (the UNIX epoch)", metricdata.UnitMilliseconds)
   478  	if err != nil {
   479  		return nil, err
   480  	}
   481  
   482  	memStats.pauseTotalNs, err = producer.createInt64DerivedCumulative("process/pause_total", "Cumulative milliseconds spent in GC stop-the-world pauses", metricdata.UnitMilliseconds)
   483  	if err != nil {
   484  		return nil, err
   485  	}
   486  
   487  	memStats.gcCPUFraction, err = producer.createFloat64GaugeEntry("process/gc_cpu_fraction", "Fraction of this program's available CPU time used by the GC since the program started", metricdata.UnitDimensionless)
   488  	if err != nil {
   489  		return nil, err
   490  	}
   491  
   492  	return memStats, nil
   493  }
   494  
   495  func (m *memStats) read() {
   496  	runtime.ReadMemStats(&m.memStats)
   497  
   498  	m.memAlloc.Set(int64(m.memStats.Alloc))
   499  
   500  	_ = m.memTotal.UpsertEntry(func() int64 {
   501  		return int64(m.memStats.TotalAlloc)
   502  	})
   503  
   504  	m.memSys.Set(int64(m.memStats.Sys))
   505  
   506  	_ = m.memLookups.UpsertEntry(func() int64 {
   507  		return int64(m.memStats.Lookups)
   508  	})
   509  
   510  	_ = m.memMalloc.UpsertEntry(func() int64 {
   511  		return int64(m.memStats.Mallocs)
   512  	})
   513  
   514  	_ = m.memFrees.UpsertEntry(func() int64 {
   515  		return int64(m.memStats.Frees)
   516  	})
   517  
   518  	m.heapAlloc.Set(int64(m.memStats.HeapAlloc))
   519  	m.heapSys.Set(int64(m.memStats.HeapSys))
   520  	m.heapIdle.Set(int64(m.memStats.HeapIdle))
   521  	m.heapInuse.Set(int64(m.memStats.HeapInuse))
   522  
   523  	_ = m.heapReleased.UpsertEntry(func() int64 {
   524  		return int64(m.memStats.HeapReleased)
   525  	})
   526  
   527  	m.heapObjects.Set(int64(m.memStats.HeapObjects))
   528  
   529  	m.stackInuse.Set(int64(m.memStats.StackInuse))
   530  	m.stackSys.Set(int64(m.memStats.StackSys))
   531  	m.stackMSpanInuse.Set(int64(m.memStats.MSpanInuse))
   532  	m.stackMSpanSys.Set(int64(m.memStats.MSpanSys))
   533  	m.stackMCacheInuse.Set(int64(m.memStats.MCacheInuse))
   534  	m.stackMCacheSys.Set(int64(m.memStats.MCacheSys))
   535  
   536  	m.gcSys.Set(int64(m.memStats.GCSys))
   537  	m.otherSys.Set(int64(m.memStats.OtherSys))
   538  
   539  	_ = m.numGC.UpsertEntry(func() int64 {
   540  		return int64(m.memStats.NumGC)
   541  	})
   542  
   543  	_ = m.numForcedGC.UpsertEntry(func() int64 {
   544  		return int64(m.memStats.NumForcedGC)
   545  	})
   546  
   547  	m.nextGC.Set(int64(m.memStats.NextGC))
   548  	m.lastGC.Set(int64(m.memStats.LastGC) / int64(time.Millisecond))
   549  
   550  	_ = m.pauseTotalNs.UpsertEntry(func() int64 {
   551  		return int64(m.memStats.PauseTotalNs) / int64(time.Millisecond)
   552  	})
   553  
   554  	m.gcCPUFraction.Set(m.memStats.GCCPUFraction)
   555  }
   556  
   557  func newCPUStats(producer *producer) (*cpuStats, error) {
   558  	cpuStats := &cpuStats{}
   559  	var err error
   560  
   561  	cpuStats.numGoroutines, err = producer.createInt64GaugeEntry("process/cpu_goroutines", "Number of goroutines that currently exist", metricdata.UnitDimensionless)
   562  	if err != nil {
   563  		return nil, err
   564  	}
   565  
   566  	cpuStats.numCgoCalls, err = producer.createInt64GaugeEntry("process/cpu_cgo_calls", "Number of cgo calls made by the current process", metricdata.UnitDimensionless)
   567  	if err != nil {
   568  		return nil, err
   569  	}
   570  
   571  	return cpuStats, nil
   572  }
   573  
   574  func (c *cpuStats) read() {
   575  	c.numGoroutines.Set(int64(runtime.NumGoroutine()))
   576  	c.numCgoCalls.Set(runtime.NumCgoCall())
   577  }
   578  
   579  func (p *producer) createFloat64GaugeEntry(name string, description string, unit metricdata.Unit) (*metric.Float64Entry, error) {
   580  	if len(p.options.Prefix) > 0 {
   581  		name = p.options.Prefix + name
   582  	}
   583  
   584  	gauge, err := p.reg.AddFloat64Gauge(
   585  		name,
   586  		metric.WithDescription(description),
   587  		metric.WithUnit(unit))
   588  	if err != nil {
   589  		return nil, errors.New("error creating gauge for " + name + ": " + err.Error())
   590  	}
   591  
   592  	entry, err := gauge.GetEntry()
   593  	if err != nil {
   594  		return nil, errors.New("error getting gauge entry for " + name + ": " + err.Error())
   595  	}
   596  
   597  	return entry, nil
   598  }
   599  
   600  func (p *producer) createInt64GaugeEntry(name string, description string, unit metricdata.Unit) (*metric.Int64GaugeEntry, error) {
   601  	if len(p.options.Prefix) > 0 {
   602  		name = p.options.Prefix + name
   603  	}
   604  
   605  	gauge, err := p.reg.AddInt64Gauge(
   606  		name,
   607  		metric.WithDescription(description),
   608  		metric.WithUnit(unit))
   609  	if err != nil {
   610  		return nil, errors.New("error creating gauge for " + name + ": " + err.Error())
   611  	}
   612  
   613  	entry, err := gauge.GetEntry()
   614  	if err != nil {
   615  		return nil, errors.New("error getting gauge entry for " + name + ": " + err.Error())
   616  	}
   617  
   618  	return entry, nil
   619  }
   620  
   621  func (p *producer) createInt64DerivedCumulative(name string, description string, unit metricdata.Unit) (*metric.Int64DerivedCumulative, error) {
   622  	if len(p.options.Prefix) > 0 {
   623  		name = p.options.Prefix + name
   624  	}
   625  
   626  	cumulative, err := p.reg.AddInt64DerivedCumulative(
   627  		name,
   628  		metric.WithDescription(description),
   629  		metric.WithUnit(unit))
   630  	if err != nil {
   631  		return nil, errors.New("error creating gauge for " + name + ": " + err.Error())
   632  	}
   633  
   634  	return cumulative, nil
   635  }
   636  

View as plain text