/**
 * Copyright 2019, OpenCensus Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ import { getTimestampWithProcessHRTime } from '../../common/time-util' ; import { validateArrayElementsNotNull , validateNotNull , } from '../../common/validations' ; import { LabelKey , LabelValue , Metric , MetricDescriptor , MetricDescriptorType , TimeSeries , Timestamp , } from '../export/types' ; import { Meter } from '../types' ; import { hashLabelValues , initializeDefaultLabels } from '../utils' ; import { CumulativePoint } from './types' ; /**
 * Cumulative metric is used to record aggregated metrics that represents a
 * single numerical value accumulated over a time interval. The value can only
 * increase or be reset to zero on restart or reset the event.
 */ export class Cumulative implements Meter { private readonly metricDescriptor : MetricDescriptor ; private labelKeysLength : number ; private defaultLabelValues : LabelValue [ ] ; private registeredPoints : Map < string , CumulativePoint > = new Map ( ) ; private readonly constantLabelValues : LabelValue [ ] ; param name param description param unit param type param labelKeys param constantLabels constructor ( name , description , unit , type , readonly labelKeys , readonly constantLabels ) { this . labelKeysLength = labelKeys . length ; const keysAndConstantKeys = [ ... labelKeys , ... constantLabels . keys ( ) ] ; this . constantLabelValues = [ ... constantLabels . values ( ) ] ; this . metricDescriptor = { name , description , unit , type , labelKeys : keysAndConstantKeys , } ; this . defaultLabelValues = initializeDefaultLabels ( this . labelKeysLength ) ; } param labelValues returns getOrCreateTimeSeries ( labelValues ) { validateArrayElementsNotNull ( validateNotNull ( labelValues , 'labelValues' ) , 'labelValue' ) ; return this . registerTimeSeries ( labelValues ) ; } returns getDefaultTimeSeries ( ) { return this . registerTimeSeries ( this . defaultLabelValues ) ; } param labelValues removeTimeSeries ( labelValues ) { validateNotNull ( labelValues , 'labelValues' ) ; this . registeredPoints . delete ( hashLabelValues ( labelValues ) ) ; } /**
     * Removes all TimeSeries from the cumulative metric. i.e. references to all
     * previous Point objects are invalid (not part of the metric).
     */ clear ( ) { this . registeredPoints . clear ( ) ; } param labelValues returns private registerTimeSeries ( labelValues ) { const hash = hashLabelValues ( labelValues ) ; if ( this . registeredPoints . has ( hash ) ) { return this . registeredPoints . get ( hash ) ! ; } if ( this . labelKeysLength !== labelValues . length ) { throw new Error ( "Label Keys and Label Values don't have same size" ) ; } const point = new CumulativePointEntry ( [ ... labelValues , ... this . constantLabelValues , ] ) ; this . registeredPoints . set ( hash , point ) ; return point ; } returns getMetric ( ) { if ( this . registeredPoints . size === 0 ) { return null ; } const now = getTimestampWithProcessHRTime ( ) ; return { descriptor : this . metricDescriptor , timeseries : Array . from ( this . registeredPoints , ( [ _ , point ] ) => point . getTimeSeries ( now ) ) , } ; } } /**
 * The value of a single point in the Cumulative.TimeSeries.
 */ export class CumulativePointEntry implements CumulativePoint { private readonly labelValues : LabelValue [ ] ; private startTimestamp : Timestamp ; private value = 0 ; constructor ( labelValues ) { this . labelValues = labelValues ; this . startTimestamp = getTimestampWithProcessHRTime ( ) ; } /** Reset cumulative metric. */ reset ( ) { this . value = 0 ; this . startTimestamp = getTimestampWithProcessHRTime ( ) ; } param val inc ( val ? ) { if ( ( val && ! Number . isFinite ( val ) ) || ( val !== undefined && isNaN ( val ) ) ) { throw new TypeError ( `Value is not a valid number: ${ val }` ) ; } if ( val && val < 0 ) { throw new Error ( 'It is not possible to decrease a cumulative metric' ) ; } const incValue = val === null || val === undefined ? 1 : val ; this . value += incValue ; } param now returns getTimeSeries ( now ) { return { labelValues : this . labelValues , points : [ { value : this . value , timestamp : now } ] , startTimestamp : this . startTimestamp , } ; } }