feat: Complete zCode CLI X with Telegram bot integration

- Add full Telegram bot functionality with Z.AI API integration
- Implement 4 tools: Bash, FileEdit, WebSearch, Git
- Add 3 agents: Code Reviewer, Architect, DevOps Engineer
- Add 6 skills for common coding tasks
- Add systemd service file for 24/7 operation
- Add nginx configuration for HTTPS webhook
- Add comprehensive documentation
- Implement WebSocket server for real-time updates
- Add logging system with Winston
- Add environment validation

🤖 zCode CLI X - Agentic coder with Z.AI + Telegram integration
This commit is contained in:
admin
2026-05-05 09:01:26 +00:00
Unverified
parent 4a7035dd92
commit 875c7f9b91
24688 changed files with 3224957 additions and 221 deletions

View File

@@ -0,0 +1,32 @@
import { HrTime } from '@opentelemetry/api';
import { Accumulation, Aggregator } from '../aggregator/types';
import { InstrumentDescriptor } from '../InstrumentDescriptor';
import { AttributesProcessor } from '../view/AttributesProcessor';
import { MetricStorage } from './MetricStorage';
import { MetricData } from '../export/MetricData';
import { Maybe } from '../utils';
import { MetricCollectorHandle } from './MetricCollector';
import { AttributeHashMap } from './HashMap';
import { AsyncWritableMetricStorage } from './WritableMetricStorage';
/**
* Internal interface.
*
* Stores and aggregates {@link MetricData} for asynchronous instruments.
*/
export declare class AsyncMetricStorage<T extends Maybe<Accumulation>> extends MetricStorage implements AsyncWritableMetricStorage {
private _attributesProcessor;
private _aggregationCardinalityLimit?;
private _deltaMetricStorage;
private _temporalMetricStorage;
constructor(_instrumentDescriptor: InstrumentDescriptor, aggregator: Aggregator<T>, _attributesProcessor: AttributesProcessor, collectorHandles: MetricCollectorHandle[], _aggregationCardinalityLimit?: number | undefined);
record(measurements: AttributeHashMap<number>, observationTime: HrTime): void;
/**
* Collects the metrics from this storage. The ObservableCallback is invoked
* during the collection.
*
* Note: This is a stateful operation and may reset any interval-related
* state for the MetricCollector.
*/
collect(collector: MetricCollectorHandle, collectionTime: HrTime): Maybe<MetricData>;
}
//# sourceMappingURL=AsyncMetricStorage.d.ts.map

View File

@@ -0,0 +1,52 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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 { MetricStorage } from './MetricStorage';
import { DeltaMetricProcessor } from './DeltaMetricProcessor';
import { TemporalMetricProcessor } from './TemporalMetricProcessor';
import { AttributeHashMap } from './HashMap';
/**
* Internal interface.
*
* Stores and aggregates {@link MetricData} for asynchronous instruments.
*/
export class AsyncMetricStorage extends MetricStorage {
constructor(_instrumentDescriptor, aggregator, _attributesProcessor, collectorHandles, _aggregationCardinalityLimit) {
super(_instrumentDescriptor);
this._attributesProcessor = _attributesProcessor;
this._aggregationCardinalityLimit = _aggregationCardinalityLimit;
this._deltaMetricStorage = new DeltaMetricProcessor(aggregator, this._aggregationCardinalityLimit);
this._temporalMetricStorage = new TemporalMetricProcessor(aggregator, collectorHandles);
}
record(measurements, observationTime) {
const processed = new AttributeHashMap();
Array.from(measurements.entries()).forEach(([attributes, value]) => {
processed.set(this._attributesProcessor.process(attributes), value);
});
this._deltaMetricStorage.batchCumulate(processed, observationTime);
}
/**
* Collects the metrics from this storage. The ObservableCallback is invoked
* during the collection.
*
* Note: This is a stateful operation and may reset any interval-related
* state for the MetricCollector.
*/
collect(collector, collectionTime) {
const accumulations = this._deltaMetricStorage.collect();
return this._temporalMetricStorage.buildMetrics(collector, this._instrumentDescriptor, accumulations, collectionTime);
}
}
//# sourceMappingURL=AsyncMetricStorage.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AsyncMetricStorage.js","sourceRoot":"","sources":["../../../src/state/AsyncMetricStorage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAGpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAG7C;;;;GAIG;AACH,MAAM,OAAO,kBACX,SAAQ,aAAa;IAMrB,YACE,qBAA2C,EAC3C,UAAyB,EACjB,oBAAyC,EACjD,gBAAyC,EACjC,4BAAqC;QAE7C,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAJrB,yBAAoB,GAApB,oBAAoB,CAAqB;QAEzC,iCAA4B,GAA5B,4BAA4B,CAAS;QAG7C,IAAI,CAAC,mBAAmB,GAAG,IAAI,oBAAoB,CACjD,UAAU,EACV,IAAI,CAAC,4BAA4B,CAClC,CAAC;QACF,IAAI,CAAC,sBAAsB,GAAG,IAAI,uBAAuB,CACvD,UAAU,EACV,gBAAgB,CACjB,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAsC,EAAE,eAAuB;QACpE,MAAM,SAAS,GAAG,IAAI,gBAAgB,EAAU,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,EAAE;YACjE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACrE,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CACL,SAAgC,EAChC,cAAsB;QAEtB,MAAM,aAAa,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;QAEzD,OAAO,IAAI,CAAC,sBAAsB,CAAC,YAAY,CAC7C,SAAS,EACT,IAAI,CAAC,qBAAqB,EAC1B,aAAa,EACb,cAAc,CACf,CAAC;IACJ,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HrTime } from '@opentelemetry/api';\nimport { Accumulation, Aggregator } from '../aggregator/types';\nimport { InstrumentDescriptor } from '../InstrumentDescriptor';\nimport { AttributesProcessor } from '../view/AttributesProcessor';\nimport { MetricStorage } from './MetricStorage';\nimport { MetricData } from '../export/MetricData';\nimport { DeltaMetricProcessor } from './DeltaMetricProcessor';\nimport { TemporalMetricProcessor } from './TemporalMetricProcessor';\nimport { Maybe } from '../utils';\nimport { MetricCollectorHandle } from './MetricCollector';\nimport { AttributeHashMap } from './HashMap';\nimport { AsyncWritableMetricStorage } from './WritableMetricStorage';\n\n/**\n * Internal interface.\n *\n * Stores and aggregates {@link MetricData} for asynchronous instruments.\n */\nexport class AsyncMetricStorage<T extends Maybe<Accumulation>>\n extends MetricStorage\n implements AsyncWritableMetricStorage\n{\n private _deltaMetricStorage: DeltaMetricProcessor<T>;\n private _temporalMetricStorage: TemporalMetricProcessor<T>;\n\n constructor(\n _instrumentDescriptor: InstrumentDescriptor,\n aggregator: Aggregator<T>,\n private _attributesProcessor: AttributesProcessor,\n collectorHandles: MetricCollectorHandle[],\n private _aggregationCardinalityLimit?: number\n ) {\n super(_instrumentDescriptor);\n this._deltaMetricStorage = new DeltaMetricProcessor(\n aggregator,\n this._aggregationCardinalityLimit\n );\n this._temporalMetricStorage = new TemporalMetricProcessor(\n aggregator,\n collectorHandles\n );\n }\n\n record(measurements: AttributeHashMap<number>, observationTime: HrTime) {\n const processed = new AttributeHashMap<number>();\n Array.from(measurements.entries()).forEach(([attributes, value]) => {\n processed.set(this._attributesProcessor.process(attributes), value);\n });\n this._deltaMetricStorage.batchCumulate(processed, observationTime);\n }\n\n /**\n * Collects the metrics from this storage. The ObservableCallback is invoked\n * during the collection.\n *\n * Note: This is a stateful operation and may reset any interval-related\n * state for the MetricCollector.\n */\n collect(\n collector: MetricCollectorHandle,\n collectionTime: HrTime\n ): Maybe<MetricData> {\n const accumulations = this._deltaMetricStorage.collect();\n\n return this._temporalMetricStorage.buildMetrics(\n collector,\n this._instrumentDescriptor,\n accumulations,\n collectionTime\n );\n }\n}\n"]}

View File

@@ -0,0 +1,28 @@
import { Context, HrTime, Attributes } from '@opentelemetry/api';
import { Maybe } from '../utils';
import { Accumulation, Aggregator } from '../aggregator/types';
import { AttributeHashMap } from './HashMap';
/**
* Internal interface.
*
* Allows synchronous collection of metrics. This processor should allow
* allocation of new aggregation cells for metrics and convert cumulative
* recording to delta data points.
*/
export declare class DeltaMetricProcessor<T extends Maybe<Accumulation>> {
private _aggregator;
private _activeCollectionStorage;
private _cumulativeMemoStorage;
private _cardinalityLimit;
private _overflowAttributes;
private _overflowHashCode;
constructor(_aggregator: Aggregator<T>, aggregationCardinalityLimit?: number);
record(value: number, attributes: Attributes, _context: Context, collectionTime: HrTime): void;
batchCumulate(measurements: AttributeHashMap<number>, collectionTime: HrTime): void;
/**
* Returns a collection of delta metrics. Start time is the when first
* time event collected.
*/
collect(): AttributeHashMap<T>;
}
//# sourceMappingURL=DeltaMetricProcessor.d.ts.map

View File

@@ -0,0 +1,94 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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 { hashAttributes } from '../utils';
import { AttributeHashMap } from './HashMap';
/**
* Internal interface.
*
* Allows synchronous collection of metrics. This processor should allow
* allocation of new aggregation cells for metrics and convert cumulative
* recording to delta data points.
*/
export class DeltaMetricProcessor {
constructor(_aggregator, aggregationCardinalityLimit) {
this._aggregator = _aggregator;
this._activeCollectionStorage = new AttributeHashMap();
// TODO: find a reasonable mean to clean the memo;
// https://github.com/open-telemetry/opentelemetry-specification/pull/2208
this._cumulativeMemoStorage = new AttributeHashMap();
this._overflowAttributes = { 'otel.metric.overflow': true };
this._cardinalityLimit = (aggregationCardinalityLimit !== null && aggregationCardinalityLimit !== void 0 ? aggregationCardinalityLimit : 2000) - 1;
this._overflowHashCode = hashAttributes(this._overflowAttributes);
}
record(value, attributes, _context, collectionTime) {
let accumulation = this._activeCollectionStorage.get(attributes);
if (!accumulation) {
if (this._activeCollectionStorage.size >= this._cardinalityLimit) {
const overflowAccumulation = this._activeCollectionStorage.getOrDefault(this._overflowAttributes, () => this._aggregator.createAccumulation(collectionTime));
overflowAccumulation === null || overflowAccumulation === void 0 ? void 0 : overflowAccumulation.record(value);
return;
}
accumulation = this._aggregator.createAccumulation(collectionTime);
this._activeCollectionStorage.set(attributes, accumulation);
}
accumulation === null || accumulation === void 0 ? void 0 : accumulation.record(value);
}
batchCumulate(measurements, collectionTime) {
Array.from(measurements.entries()).forEach(([attributes, value, hashCode]) => {
const accumulation = this._aggregator.createAccumulation(collectionTime);
accumulation === null || accumulation === void 0 ? void 0 : accumulation.record(value);
let delta = accumulation;
// Diff with recorded cumulative memo.
if (this._cumulativeMemoStorage.has(attributes, hashCode)) {
// has() returned true, previous is present.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const previous = this._cumulativeMemoStorage.get(attributes, hashCode);
delta = this._aggregator.diff(previous, accumulation);
}
else {
// If the cardinality limit is reached, we need to change the attributes
if (this._cumulativeMemoStorage.size >= this._cardinalityLimit) {
attributes = this._overflowAttributes;
hashCode = this._overflowHashCode;
if (this._cumulativeMemoStorage.has(attributes, hashCode)) {
const previous = this._cumulativeMemoStorage.get(attributes, hashCode);
delta = this._aggregator.diff(previous, accumulation);
}
}
}
// Merge with uncollected active delta.
if (this._activeCollectionStorage.has(attributes, hashCode)) {
// has() returned true, previous is present.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const active = this._activeCollectionStorage.get(attributes, hashCode);
delta = this._aggregator.merge(active, delta);
}
// Save the current record and the delta record.
this._cumulativeMemoStorage.set(attributes, accumulation, hashCode);
this._activeCollectionStorage.set(attributes, delta, hashCode);
});
}
/**
* Returns a collection of delta metrics. Start time is the when first
* time event collected.
*/
collect() {
const unreportedDelta = this._activeCollectionStorage;
this._activeCollectionStorage = new AttributeHashMap();
return unreportedDelta;
}
}
//# sourceMappingURL=DeltaMetricProcessor.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,21 @@
import { Attributes } from '@opentelemetry/api';
export interface Hash<ValueType, HashCodeType> {
(value: ValueType): HashCodeType;
}
export declare class HashMap<KeyType, ValueType, HashCodeType> {
private _hash;
private _valueMap;
private _keyMap;
constructor(_hash: Hash<KeyType, HashCodeType>);
get(key: KeyType, hashCode?: HashCodeType): ValueType | undefined;
getOrDefault(key: KeyType, defaultFactory: () => ValueType): ValueType | undefined;
set(key: KeyType, value: ValueType, hashCode?: HashCodeType): void;
has(key: KeyType, hashCode?: HashCodeType): boolean;
keys(): IterableIterator<[KeyType, HashCodeType]>;
entries(): IterableIterator<[KeyType, ValueType, HashCodeType]>;
get size(): number;
}
export declare class AttributeHashMap<ValueType> extends HashMap<Attributes, ValueType, string> {
constructor();
}
//# sourceMappingURL=HashMap.d.ts.map

View File

@@ -0,0 +1,77 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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 { hashAttributes } from '../utils';
export class HashMap {
constructor(_hash) {
this._hash = _hash;
this._valueMap = new Map();
this._keyMap = new Map();
}
get(key, hashCode) {
hashCode !== null && hashCode !== void 0 ? hashCode : (hashCode = this._hash(key));
return this._valueMap.get(hashCode);
}
getOrDefault(key, defaultFactory) {
const hash = this._hash(key);
if (this._valueMap.has(hash)) {
return this._valueMap.get(hash);
}
const val = defaultFactory();
if (!this._keyMap.has(hash)) {
this._keyMap.set(hash, key);
}
this._valueMap.set(hash, val);
return val;
}
set(key, value, hashCode) {
hashCode !== null && hashCode !== void 0 ? hashCode : (hashCode = this._hash(key));
if (!this._keyMap.has(hashCode)) {
this._keyMap.set(hashCode, key);
}
this._valueMap.set(hashCode, value);
}
has(key, hashCode) {
hashCode !== null && hashCode !== void 0 ? hashCode : (hashCode = this._hash(key));
return this._valueMap.has(hashCode);
}
*keys() {
const keyIterator = this._keyMap.entries();
let next = keyIterator.next();
while (next.done !== true) {
yield [next.value[1], next.value[0]];
next = keyIterator.next();
}
}
*entries() {
const valueIterator = this._valueMap.entries();
let next = valueIterator.next();
while (next.done !== true) {
// next.value[0] here can not be undefined
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
yield [this._keyMap.get(next.value[0]), next.value[1], next.value[0]];
next = valueIterator.next();
}
}
get size() {
return this._valueMap.size;
}
}
export class AttributeHashMap extends HashMap {
constructor() {
super(hashAttributes);
}
}
//# sourceMappingURL=HashMap.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
import { InstrumentationScope } from '@opentelemetry/core';
import { IResource } from '@opentelemetry/resources';
import { Aggregation, InstrumentType } from '..';
import { ViewRegistry } from '../view/ViewRegistry';
import { MeterSharedState } from './MeterSharedState';
import { MetricCollector, MetricCollectorHandle } from './MetricCollector';
/**
* An internal record for shared meter provider states.
*/
export declare class MeterProviderSharedState {
resource: IResource;
viewRegistry: ViewRegistry;
metricCollectors: MetricCollector[];
meterSharedStates: Map<string, MeterSharedState>;
constructor(resource: IResource);
getMeterSharedState(instrumentationScope: InstrumentationScope): MeterSharedState;
selectAggregations(instrumentType: InstrumentType): [MetricCollectorHandle, Aggregation][];
}
//# sourceMappingURL=MeterProviderSharedState.d.ts.map

View File

@@ -0,0 +1,46 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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 { instrumentationScopeId } from '../utils';
import { ViewRegistry } from '../view/ViewRegistry';
import { MeterSharedState } from './MeterSharedState';
/**
* An internal record for shared meter provider states.
*/
export class MeterProviderSharedState {
constructor(resource) {
this.resource = resource;
this.viewRegistry = new ViewRegistry();
this.metricCollectors = [];
this.meterSharedStates = new Map();
}
getMeterSharedState(instrumentationScope) {
const id = instrumentationScopeId(instrumentationScope);
let meterSharedState = this.meterSharedStates.get(id);
if (meterSharedState == null) {
meterSharedState = new MeterSharedState(this, instrumentationScope);
this.meterSharedStates.set(id, meterSharedState);
}
return meterSharedState;
}
selectAggregations(instrumentType) {
const result = [];
for (const collector of this.metricCollectors) {
result.push([collector, collector.selectAggregation(instrumentType)]);
}
return result;
}
}
//# sourceMappingURL=MeterProviderSharedState.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"MeterProviderSharedState.js","sourceRoot":"","sources":["../../../src/state/MeterProviderSharedState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD;;GAEG;AACH,MAAM,OAAO,wBAAwB;IAOnC,YAAmB,QAAmB;QAAnB,aAAQ,GAAR,QAAQ,CAAW;QANtC,iBAAY,GAAG,IAAI,YAAY,EAAE,CAAC;QAElC,qBAAgB,GAAsB,EAAE,CAAC;QAEzC,sBAAiB,GAAkC,IAAI,GAAG,EAAE,CAAC;IAEpB,CAAC;IAE1C,mBAAmB,CAAC,oBAA0C;QAC5D,MAAM,EAAE,GAAG,sBAAsB,CAAC,oBAAoB,CAAC,CAAC;QACxD,IAAI,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,gBAAgB,IAAI,IAAI,EAAE;YAC5B,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;YACpE,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;SAClD;QACD,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,kBAAkB,CAAC,cAA8B;QAC/C,MAAM,MAAM,GAA2C,EAAE,CAAC;QAC1D,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,gBAAgB,EAAE;YAC7C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;SACvE;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { InstrumentationScope } from '@opentelemetry/core';\nimport { IResource } from '@opentelemetry/resources';\nimport { Aggregation, InstrumentType } from '..';\nimport { instrumentationScopeId } from '../utils';\nimport { ViewRegistry } from '../view/ViewRegistry';\nimport { MeterSharedState } from './MeterSharedState';\nimport { MetricCollector, MetricCollectorHandle } from './MetricCollector';\n\n/**\n * An internal record for shared meter provider states.\n */\nexport class MeterProviderSharedState {\n viewRegistry = new ViewRegistry();\n\n metricCollectors: MetricCollector[] = [];\n\n meterSharedStates: Map<string, MeterSharedState> = new Map();\n\n constructor(public resource: IResource) {}\n\n getMeterSharedState(instrumentationScope: InstrumentationScope) {\n const id = instrumentationScopeId(instrumentationScope);\n let meterSharedState = this.meterSharedStates.get(id);\n if (meterSharedState == null) {\n meterSharedState = new MeterSharedState(this, instrumentationScope);\n this.meterSharedStates.set(id, meterSharedState);\n }\n return meterSharedState;\n }\n\n selectAggregations(instrumentType: InstrumentType) {\n const result: [MetricCollectorHandle, Aggregation][] = [];\n for (const collector of this.metricCollectors) {\n result.push([collector, collector.selectAggregation(instrumentType)]);\n }\n return result;\n }\n}\n"]}

View File

@@ -0,0 +1,42 @@
import { HrTime } from '@opentelemetry/api';
import { InstrumentationScope } from '@opentelemetry/core';
import { MetricCollectOptions } from '../export/MetricProducer';
import { ScopeMetrics } from '../export/MetricData';
import { InstrumentDescriptor } from '../InstrumentDescriptor';
import { Meter } from '../Meter';
import { Maybe } from '../utils';
import { AsyncMetricStorage } from './AsyncMetricStorage';
import { MeterProviderSharedState } from './MeterProviderSharedState';
import { MetricCollectorHandle } from './MetricCollector';
import { MetricStorageRegistry } from './MetricStorageRegistry';
import { MultiMetricStorage } from './MultiWritableMetricStorage';
import { ObservableRegistry } from './ObservableRegistry';
import { SyncMetricStorage } from './SyncMetricStorage';
import { Accumulation } from '../aggregator/types';
/**
* An internal record for shared meter provider states.
*/
export declare class MeterSharedState {
private _meterProviderSharedState;
private _instrumentationScope;
metricStorageRegistry: MetricStorageRegistry;
observableRegistry: ObservableRegistry;
meter: Meter;
constructor(_meterProviderSharedState: MeterProviderSharedState, _instrumentationScope: InstrumentationScope);
registerMetricStorage(descriptor: InstrumentDescriptor): MultiMetricStorage | SyncMetricStorage<Maybe<Accumulation>>;
registerAsyncMetricStorage(descriptor: InstrumentDescriptor): AsyncMetricStorage<Maybe<Accumulation>>[];
/**
* @param collector opaque handle of {@link MetricCollector} which initiated the collection.
* @param collectionTime the HrTime at which the collection was initiated.
* @param options options for collection.
* @returns the list of metric data collected.
*/
collect(collector: MetricCollectorHandle, collectionTime: HrTime, options?: MetricCollectOptions): Promise<ScopeMetricsResult | null>;
private _registerMetricStorage;
}
interface ScopeMetricsResult {
scopeMetrics?: ScopeMetrics;
errors: unknown[];
}
export {};
//# sourceMappingURL=MeterSharedState.d.ts.map

View File

@@ -0,0 +1,113 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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 { createInstrumentDescriptorWithView, } from '../InstrumentDescriptor';
import { Meter } from '../Meter';
import { isNotNullish } from '../utils';
import { AsyncMetricStorage } from './AsyncMetricStorage';
import { MetricStorageRegistry } from './MetricStorageRegistry';
import { MultiMetricStorage } from './MultiWritableMetricStorage';
import { ObservableRegistry } from './ObservableRegistry';
import { SyncMetricStorage } from './SyncMetricStorage';
import { AttributesProcessor } from '../view/AttributesProcessor';
/**
* An internal record for shared meter provider states.
*/
export class MeterSharedState {
constructor(_meterProviderSharedState, _instrumentationScope) {
this._meterProviderSharedState = _meterProviderSharedState;
this._instrumentationScope = _instrumentationScope;
this.metricStorageRegistry = new MetricStorageRegistry();
this.observableRegistry = new ObservableRegistry();
this.meter = new Meter(this);
}
registerMetricStorage(descriptor) {
const storages = this._registerMetricStorage(descriptor, SyncMetricStorage);
if (storages.length === 1) {
return storages[0];
}
return new MultiMetricStorage(storages);
}
registerAsyncMetricStorage(descriptor) {
const storages = this._registerMetricStorage(descriptor, AsyncMetricStorage);
return storages;
}
/**
* @param collector opaque handle of {@link MetricCollector} which initiated the collection.
* @param collectionTime the HrTime at which the collection was initiated.
* @param options options for collection.
* @returns the list of metric data collected.
*/
async collect(collector, collectionTime, options) {
/**
* 1. Call all observable callbacks first.
* 2. Collect metric result for the collector.
*/
const errors = await this.observableRegistry.observe(collectionTime, options === null || options === void 0 ? void 0 : options.timeoutMillis);
const storages = this.metricStorageRegistry.getStorages(collector);
// prevent more allocations if there are no storages.
if (storages.length === 0) {
return null;
}
const metricDataList = storages
.map(metricStorage => {
return metricStorage.collect(collector, collectionTime);
})
.filter(isNotNullish);
// skip this scope if no data was collected (storage created, but no data observed)
if (metricDataList.length === 0) {
return { errors };
}
return {
scopeMetrics: {
scope: this._instrumentationScope,
metrics: metricDataList,
},
errors,
};
}
_registerMetricStorage(descriptor, MetricStorageType) {
const views = this._meterProviderSharedState.viewRegistry.findViews(descriptor, this._instrumentationScope);
let storages = views.map(view => {
const viewDescriptor = createInstrumentDescriptorWithView(view, descriptor);
const compatibleStorage = this.metricStorageRegistry.findOrUpdateCompatibleStorage(viewDescriptor);
if (compatibleStorage != null) {
return compatibleStorage;
}
const aggregator = view.aggregation.createAggregator(viewDescriptor);
const viewStorage = new MetricStorageType(viewDescriptor, aggregator, view.attributesProcessor, this._meterProviderSharedState.metricCollectors, view.aggregationCardinalityLimit);
this.metricStorageRegistry.register(viewStorage);
return viewStorage;
});
// Fallback to the per-collector aggregations if no view is configured for the instrument.
if (storages.length === 0) {
const perCollectorAggregations = this._meterProviderSharedState.selectAggregations(descriptor.type);
const collectorStorages = perCollectorAggregations.map(([collector, aggregation]) => {
const compatibleStorage = this.metricStorageRegistry.findOrUpdateCompatibleCollectorStorage(collector, descriptor);
if (compatibleStorage != null) {
return compatibleStorage;
}
const aggregator = aggregation.createAggregator(descriptor);
const cardinalityLimit = collector.selectCardinalityLimit(descriptor.type);
const storage = new MetricStorageType(descriptor, aggregator, AttributesProcessor.Noop(), [collector], cardinalityLimit);
this.metricStorageRegistry.registerForCollector(collector, storage);
return storage;
});
storages = storages.concat(collectorStorages);
}
return storages;
}
}
//# sourceMappingURL=MeterSharedState.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,42 @@
import { AggregationTemporalitySelector } from '../export/AggregationSelector';
import { CollectionResult } from '../export/MetricData';
import { MetricProducer, MetricCollectOptions } from '../export/MetricProducer';
import { MetricReader } from '../export/MetricReader';
import { InstrumentType } from '../InstrumentDescriptor';
import { ForceFlushOptions, ShutdownOptions } from '../types';
import { MeterProviderSharedState } from './MeterProviderSharedState';
/**
* An internal opaque interface that the MetricReader receives as
* MetricProducer. It acts as the storage key to the internal metric stream
* state for each MetricReader.
*/
export declare class MetricCollector implements MetricProducer {
private _sharedState;
private _metricReader;
constructor(_sharedState: MeterProviderSharedState, _metricReader: MetricReader);
collect(options?: MetricCollectOptions): Promise<CollectionResult>;
/**
* Delegates for MetricReader.forceFlush.
*/
forceFlush(options?: ForceFlushOptions): Promise<void>;
/**
* Delegates for MetricReader.shutdown.
*/
shutdown(options?: ShutdownOptions): Promise<void>;
selectAggregationTemporality(instrumentType: InstrumentType): import("..").AggregationTemporality;
selectAggregation(instrumentType: InstrumentType): import("..").Aggregation;
/**
* Select the cardinality limit for the given {@link InstrumentType} for this
* collector.
*/
selectCardinalityLimit(instrumentType: InstrumentType): number;
}
/**
* An internal interface for MetricCollector. Exposes the necessary
* information for metric collection.
*/
export interface MetricCollectorHandle {
selectAggregationTemporality: AggregationTemporalitySelector;
selectCardinalityLimit(instrumentType: InstrumentType): number;
}
//# sourceMappingURL=MetricCollector.d.ts.map

View File

@@ -0,0 +1,78 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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 { millisToHrTime } from '@opentelemetry/core';
/**
* An internal opaque interface that the MetricReader receives as
* MetricProducer. It acts as the storage key to the internal metric stream
* state for each MetricReader.
*/
export class MetricCollector {
constructor(_sharedState, _metricReader) {
this._sharedState = _sharedState;
this._metricReader = _metricReader;
}
async collect(options) {
const collectionTime = millisToHrTime(Date.now());
const scopeMetrics = [];
const errors = [];
const meterCollectionPromises = Array.from(this._sharedState.meterSharedStates.values()).map(async (meterSharedState) => {
const current = await meterSharedState.collect(this, collectionTime, options);
// only add scope metrics if available
if ((current === null || current === void 0 ? void 0 : current.scopeMetrics) != null) {
scopeMetrics.push(current.scopeMetrics);
}
// only add errors if available
if ((current === null || current === void 0 ? void 0 : current.errors) != null) {
errors.push(...current.errors);
}
});
await Promise.all(meterCollectionPromises);
return {
resourceMetrics: {
resource: this._sharedState.resource,
scopeMetrics: scopeMetrics,
},
errors: errors,
};
}
/**
* Delegates for MetricReader.forceFlush.
*/
async forceFlush(options) {
await this._metricReader.forceFlush(options);
}
/**
* Delegates for MetricReader.shutdown.
*/
async shutdown(options) {
await this._metricReader.shutdown(options);
}
selectAggregationTemporality(instrumentType) {
return this._metricReader.selectAggregationTemporality(instrumentType);
}
selectAggregation(instrumentType) {
return this._metricReader.selectAggregation(instrumentType);
}
/**
* Select the cardinality limit for the given {@link InstrumentType} for this
* collector.
*/
selectCardinalityLimit(instrumentType) {
var _a, _b, _c;
return (_c = (_b = (_a = this._metricReader).selectCardinalityLimit) === null || _b === void 0 ? void 0 : _b.call(_a, instrumentType)) !== null && _c !== void 0 ? _c : 2000;
}
}
//# sourceMappingURL=MetricCollector.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,24 @@
import { HrTime } from '@opentelemetry/api';
import { MetricData } from '../export/MetricData';
import { Maybe } from '../utils';
import { MetricCollectorHandle } from './MetricCollector';
import { InstrumentDescriptor } from '../InstrumentDescriptor';
/**
* Internal interface.
*
* Represents a storage from which we can collect metrics.
*/
export declare abstract class MetricStorage {
protected _instrumentDescriptor: InstrumentDescriptor;
constructor(_instrumentDescriptor: InstrumentDescriptor);
/**
* Collects the metrics from this storage.
*
* Note: This is a stateful operation and may reset any interval-related
* state for the MetricCollector.
*/
abstract collect(collector: MetricCollectorHandle, collectionTime: HrTime): Maybe<MetricData>;
getInstrumentDescriptor(): Readonly<InstrumentDescriptor>;
updateDescription(description: string): void;
}
//# sourceMappingURL=MetricStorage.d.ts.map

View File

@@ -0,0 +1,38 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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 { createInstrumentDescriptor, } from '../InstrumentDescriptor';
/**
* Internal interface.
*
* Represents a storage from which we can collect metrics.
*/
export class MetricStorage {
constructor(_instrumentDescriptor) {
this._instrumentDescriptor = _instrumentDescriptor;
}
getInstrumentDescriptor() {
return this._instrumentDescriptor;
}
updateDescription(description) {
this._instrumentDescriptor = createInstrumentDescriptor(this._instrumentDescriptor.name, this._instrumentDescriptor.type, {
description: description,
valueType: this._instrumentDescriptor.valueType,
unit: this._instrumentDescriptor.unit,
advice: this._instrumentDescriptor.advice,
});
}
}
//# sourceMappingURL=MetricStorage.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"MetricStorage.js","sourceRoot":"","sources":["../../../src/state/MetricStorage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EACL,0BAA0B,GAE3B,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,MAAM,OAAgB,aAAa;IACjC,YAAsB,qBAA2C;QAA3C,0BAAqB,GAArB,qBAAqB,CAAsB;IAAG,CAAC;IAarE,uBAAuB;QACrB,OAAO,IAAI,CAAC,qBAAqB,CAAC;IACpC,CAAC;IAED,iBAAiB,CAAC,WAAmB;QACnC,IAAI,CAAC,qBAAqB,GAAG,0BAA0B,CACrD,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAC/B,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAC/B;YACE,WAAW,EAAE,WAAW;YACxB,SAAS,EAAE,IAAI,CAAC,qBAAqB,CAAC,SAAS;YAC/C,IAAI,EAAE,IAAI,CAAC,qBAAqB,CAAC,IAAI;YACrC,MAAM,EAAE,IAAI,CAAC,qBAAqB,CAAC,MAAM;SAC1C,CACF,CAAC;IACJ,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HrTime } from '@opentelemetry/api';\nimport { MetricData } from '../export/MetricData';\nimport { Maybe } from '../utils';\nimport { MetricCollectorHandle } from './MetricCollector';\nimport {\n createInstrumentDescriptor,\n InstrumentDescriptor,\n} from '../InstrumentDescriptor';\n\n/**\n * Internal interface.\n *\n * Represents a storage from which we can collect metrics.\n */\nexport abstract class MetricStorage {\n constructor(protected _instrumentDescriptor: InstrumentDescriptor) {}\n\n /**\n * Collects the metrics from this storage.\n *\n * Note: This is a stateful operation and may reset any interval-related\n * state for the MetricCollector.\n */\n abstract collect(\n collector: MetricCollectorHandle,\n collectionTime: HrTime\n ): Maybe<MetricData>;\n\n getInstrumentDescriptor(): Readonly<InstrumentDescriptor> {\n return this._instrumentDescriptor;\n }\n\n updateDescription(description: string): void {\n this._instrumentDescriptor = createInstrumentDescriptor(\n this._instrumentDescriptor.name,\n this._instrumentDescriptor.type,\n {\n description: description,\n valueType: this._instrumentDescriptor.valueType,\n unit: this._instrumentDescriptor.unit,\n advice: this._instrumentDescriptor.advice,\n }\n );\n }\n}\n"]}

View File

@@ -0,0 +1,19 @@
import { MetricStorage } from './MetricStorage';
import { InstrumentDescriptor } from '../InstrumentDescriptor';
import { MetricCollectorHandle } from './MetricCollector';
/**
* Internal class for storing {@link MetricStorage}
*/
export declare class MetricStorageRegistry {
private readonly _sharedRegistry;
private readonly _perCollectorRegistry;
static create(): MetricStorageRegistry;
getStorages(collector: MetricCollectorHandle): MetricStorage[];
register(storage: MetricStorage): void;
registerForCollector(collector: MetricCollectorHandle, storage: MetricStorage): void;
findOrUpdateCompatibleStorage<T extends MetricStorage>(expectedDescriptor: InstrumentDescriptor): T | null;
findOrUpdateCompatibleCollectorStorage<T extends MetricStorage>(collector: MetricCollectorHandle, expectedDescriptor: InstrumentDescriptor): T | null;
private _registerStorage;
private _findOrUpdateCompatibleStorage;
}
//# sourceMappingURL=MetricStorageRegistry.d.ts.map

View File

@@ -0,0 +1,110 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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 { isDescriptorCompatibleWith, } from '../InstrumentDescriptor';
import * as api from '@opentelemetry/api';
import { getConflictResolutionRecipe, getIncompatibilityDetails, } from '../view/RegistrationConflicts';
/**
* Internal class for storing {@link MetricStorage}
*/
export class MetricStorageRegistry {
constructor() {
this._sharedRegistry = new Map();
this._perCollectorRegistry = new Map();
}
static create() {
return new MetricStorageRegistry();
}
getStorages(collector) {
let storages = [];
for (const metricStorages of this._sharedRegistry.values()) {
storages = storages.concat(metricStorages);
}
const perCollectorStorages = this._perCollectorRegistry.get(collector);
if (perCollectorStorages != null) {
for (const metricStorages of perCollectorStorages.values()) {
storages = storages.concat(metricStorages);
}
}
return storages;
}
register(storage) {
this._registerStorage(storage, this._sharedRegistry);
}
registerForCollector(collector, storage) {
let storageMap = this._perCollectorRegistry.get(collector);
if (storageMap == null) {
storageMap = new Map();
this._perCollectorRegistry.set(collector, storageMap);
}
this._registerStorage(storage, storageMap);
}
findOrUpdateCompatibleStorage(expectedDescriptor) {
const storages = this._sharedRegistry.get(expectedDescriptor.name);
if (storages === undefined) {
return null;
}
// If the descriptor is compatible, the type of their metric storage
// (either SyncMetricStorage or AsyncMetricStorage) must be compatible.
return this._findOrUpdateCompatibleStorage(expectedDescriptor, storages);
}
findOrUpdateCompatibleCollectorStorage(collector, expectedDescriptor) {
const storageMap = this._perCollectorRegistry.get(collector);
if (storageMap === undefined) {
return null;
}
const storages = storageMap.get(expectedDescriptor.name);
if (storages === undefined) {
return null;
}
// If the descriptor is compatible, the type of their metric storage
// (either SyncMetricStorage or AsyncMetricStorage) must be compatible.
return this._findOrUpdateCompatibleStorage(expectedDescriptor, storages);
}
_registerStorage(storage, storageMap) {
const descriptor = storage.getInstrumentDescriptor();
const storages = storageMap.get(descriptor.name);
if (storages === undefined) {
storageMap.set(descriptor.name, [storage]);
return;
}
storages.push(storage);
}
_findOrUpdateCompatibleStorage(expectedDescriptor, existingStorages) {
let compatibleStorage = null;
for (const existingStorage of existingStorages) {
const existingDescriptor = existingStorage.getInstrumentDescriptor();
if (isDescriptorCompatibleWith(existingDescriptor, expectedDescriptor)) {
// Use the longer description if it does not match.
if (existingDescriptor.description !== expectedDescriptor.description) {
if (expectedDescriptor.description.length >
existingDescriptor.description.length) {
existingStorage.updateDescription(expectedDescriptor.description);
}
api.diag.warn('A view or instrument with the name ', expectedDescriptor.name, ' has already been registered, but has a different description and is incompatible with another registered view.\n', 'Details:\n', getIncompatibilityDetails(existingDescriptor, expectedDescriptor), 'The longer description will be used.\nTo resolve the conflict:', getConflictResolutionRecipe(existingDescriptor, expectedDescriptor));
}
// Storage is fully compatible. There will never be more than one pre-existing fully compatible storage.
compatibleStorage = existingStorage;
}
else {
// The implementation SHOULD warn about duplicate instrument registration
// conflicts after applying View configuration.
api.diag.warn('A view or instrument with the name ', expectedDescriptor.name, ' has already been registered and is incompatible with another registered view.\n', 'Details:\n', getIncompatibilityDetails(existingDescriptor, expectedDescriptor), 'To resolve the conflict:\n', getConflictResolutionRecipe(existingDescriptor, expectedDescriptor));
}
}
return compatibleStorage;
}
}
//# sourceMappingURL=MetricStorageRegistry.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
import { Context, HrTime, Attributes } from '@opentelemetry/api';
import { WritableMetricStorage } from './WritableMetricStorage';
/**
* Internal interface.
*/
export declare class MultiMetricStorage implements WritableMetricStorage {
private readonly _backingStorages;
constructor(_backingStorages: WritableMetricStorage[]);
record(value: number, attributes: Attributes, context: Context, recordTime: HrTime): void;
}
//# sourceMappingURL=MultiWritableMetricStorage.d.ts.map

View File

@@ -0,0 +1,29 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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.
*/
/**
* Internal interface.
*/
export class MultiMetricStorage {
constructor(_backingStorages) {
this._backingStorages = _backingStorages;
}
record(value, attributes, context, recordTime) {
this._backingStorages.forEach(it => {
it.record(value, attributes, context, recordTime);
});
}
}
//# sourceMappingURL=MultiWritableMetricStorage.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"MultiWritableMetricStorage.js","sourceRoot":"","sources":["../../../src/state/MultiWritableMetricStorage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH;;GAEG;AACH,MAAM,OAAO,kBAAkB;IAC7B,YAA6B,gBAAyC;QAAzC,qBAAgB,GAAhB,gBAAgB,CAAyB;IAAG,CAAC;IAE1E,MAAM,CACJ,KAAa,EACb,UAAsB,EACtB,OAAgB,EAChB,UAAkB;QAElB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;YACjC,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Context, HrTime, Attributes } from '@opentelemetry/api';\nimport { WritableMetricStorage } from './WritableMetricStorage';\n\n/**\n * Internal interface.\n */\nexport class MultiMetricStorage implements WritableMetricStorage {\n constructor(private readonly _backingStorages: WritableMetricStorage[]) {}\n\n record(\n value: number,\n attributes: Attributes,\n context: Context,\n recordTime: HrTime\n ) {\n this._backingStorages.forEach(it => {\n it.record(value, attributes, context, recordTime);\n });\n }\n}\n"]}

View File

@@ -0,0 +1,25 @@
import { HrTime, BatchObservableCallback, Observable, ObservableCallback } from '@opentelemetry/api';
import { ObservableInstrument } from '../Instruments';
/**
* An internal interface for managing ObservableCallbacks.
*
* Every registered callback associated with a set of instruments are be evaluated
* exactly once during collection prior to reading data for that instrument.
*/
export declare class ObservableRegistry {
private _callbacks;
private _batchCallbacks;
addCallback(callback: ObservableCallback, instrument: ObservableInstrument): void;
removeCallback(callback: ObservableCallback, instrument: ObservableInstrument): void;
addBatchCallback(callback: BatchObservableCallback, instruments: Observable[]): void;
removeBatchCallback(callback: BatchObservableCallback, instruments: Observable[]): void;
/**
* @returns a promise of rejected reasons for invoking callbacks.
*/
observe(collectionTime: HrTime, timeoutMillis?: number): Promise<unknown[]>;
private _observeCallbacks;
private _observeBatchCallbacks;
private _findCallback;
private _findBatchCallback;
}
//# sourceMappingURL=ObservableRegistry.d.ts.map

View File

@@ -0,0 +1,126 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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 { diag, } from '@opentelemetry/api';
import { isObservableInstrument } from '../Instruments';
import { BatchObservableResultImpl, ObservableResultImpl, } from '../ObservableResult';
import { callWithTimeout, PromiseAllSettled, isPromiseAllSettledRejectionResult, setEquals, } from '../utils';
/**
* An internal interface for managing ObservableCallbacks.
*
* Every registered callback associated with a set of instruments are be evaluated
* exactly once during collection prior to reading data for that instrument.
*/
export class ObservableRegistry {
constructor() {
this._callbacks = [];
this._batchCallbacks = [];
}
addCallback(callback, instrument) {
const idx = this._findCallback(callback, instrument);
if (idx >= 0) {
return;
}
this._callbacks.push({ callback, instrument });
}
removeCallback(callback, instrument) {
const idx = this._findCallback(callback, instrument);
if (idx < 0) {
return;
}
this._callbacks.splice(idx, 1);
}
addBatchCallback(callback, instruments) {
// Create a set of unique instruments.
const observableInstruments = new Set(instruments.filter(isObservableInstrument));
if (observableInstruments.size === 0) {
diag.error('BatchObservableCallback is not associated with valid instruments', instruments);
return;
}
const idx = this._findBatchCallback(callback, observableInstruments);
if (idx >= 0) {
return;
}
this._batchCallbacks.push({ callback, instruments: observableInstruments });
}
removeBatchCallback(callback, instruments) {
// Create a set of unique instruments.
const observableInstruments = new Set(instruments.filter(isObservableInstrument));
const idx = this._findBatchCallback(callback, observableInstruments);
if (idx < 0) {
return;
}
this._batchCallbacks.splice(idx, 1);
}
/**
* @returns a promise of rejected reasons for invoking callbacks.
*/
async observe(collectionTime, timeoutMillis) {
const callbackFutures = this._observeCallbacks(collectionTime, timeoutMillis);
const batchCallbackFutures = this._observeBatchCallbacks(collectionTime, timeoutMillis);
const results = await PromiseAllSettled([
...callbackFutures,
...batchCallbackFutures,
]);
const rejections = results
.filter(isPromiseAllSettledRejectionResult)
.map(it => it.reason);
return rejections;
}
_observeCallbacks(observationTime, timeoutMillis) {
return this._callbacks.map(async ({ callback, instrument }) => {
const observableResult = new ObservableResultImpl(instrument._descriptor.name, instrument._descriptor.valueType);
let callPromise = Promise.resolve(callback(observableResult));
if (timeoutMillis != null) {
callPromise = callWithTimeout(callPromise, timeoutMillis);
}
await callPromise;
instrument._metricStorages.forEach(metricStorage => {
metricStorage.record(observableResult._buffer, observationTime);
});
});
}
_observeBatchCallbacks(observationTime, timeoutMillis) {
return this._batchCallbacks.map(async ({ callback, instruments }) => {
const observableResult = new BatchObservableResultImpl();
let callPromise = Promise.resolve(callback(observableResult));
if (timeoutMillis != null) {
callPromise = callWithTimeout(callPromise, timeoutMillis);
}
await callPromise;
instruments.forEach(instrument => {
const buffer = observableResult._buffer.get(instrument);
if (buffer == null) {
return;
}
instrument._metricStorages.forEach(metricStorage => {
metricStorage.record(buffer, observationTime);
});
});
});
}
_findCallback(callback, instrument) {
return this._callbacks.findIndex(record => {
return record.callback === callback && record.instrument === instrument;
});
}
_findBatchCallback(callback, instruments) {
return this._batchCallbacks.findIndex(record => {
return (record.callback === callback &&
setEquals(record.instruments, instruments));
});
}
}
//# sourceMappingURL=ObservableRegistry.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,30 @@
import { Context, HrTime, Attributes } from '@opentelemetry/api';
import { WritableMetricStorage } from './WritableMetricStorage';
import { Accumulation, Aggregator } from '../aggregator/types';
import { InstrumentDescriptor } from '../InstrumentDescriptor';
import { AttributesProcessor } from '../view/AttributesProcessor';
import { MetricStorage } from './MetricStorage';
import { MetricData } from '../export/MetricData';
import { Maybe } from '../utils';
import { MetricCollectorHandle } from './MetricCollector';
/**
* Internal interface.
*
* Stores and aggregates {@link MetricData} for synchronous instruments.
*/
export declare class SyncMetricStorage<T extends Maybe<Accumulation>> extends MetricStorage implements WritableMetricStorage {
private _attributesProcessor;
private _aggregationCardinalityLimit?;
private _deltaMetricStorage;
private _temporalMetricStorage;
constructor(instrumentDescriptor: InstrumentDescriptor, aggregator: Aggregator<T>, _attributesProcessor: AttributesProcessor, collectorHandles: MetricCollectorHandle[], _aggregationCardinalityLimit?: number | undefined);
record(value: number, attributes: Attributes, context: Context, recordTime: HrTime): void;
/**
* Collects the metrics from this storage.
*
* Note: This is a stateful operation and may reset any interval-related
* state for the MetricCollector.
*/
collect(collector: MetricCollectorHandle, collectionTime: HrTime): Maybe<MetricData>;
}
//# sourceMappingURL=SyncMetricStorage.d.ts.map

View File

@@ -0,0 +1,47 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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 { MetricStorage } from './MetricStorage';
import { DeltaMetricProcessor } from './DeltaMetricProcessor';
import { TemporalMetricProcessor } from './TemporalMetricProcessor';
/**
* Internal interface.
*
* Stores and aggregates {@link MetricData} for synchronous instruments.
*/
export class SyncMetricStorage extends MetricStorage {
constructor(instrumentDescriptor, aggregator, _attributesProcessor, collectorHandles, _aggregationCardinalityLimit) {
super(instrumentDescriptor);
this._attributesProcessor = _attributesProcessor;
this._aggregationCardinalityLimit = _aggregationCardinalityLimit;
this._deltaMetricStorage = new DeltaMetricProcessor(aggregator, this._aggregationCardinalityLimit);
this._temporalMetricStorage = new TemporalMetricProcessor(aggregator, collectorHandles);
}
record(value, attributes, context, recordTime) {
attributes = this._attributesProcessor.process(attributes, context);
this._deltaMetricStorage.record(value, attributes, context, recordTime);
}
/**
* Collects the metrics from this storage.
*
* Note: This is a stateful operation and may reset any interval-related
* state for the MetricCollector.
*/
collect(collector, collectionTime) {
const accumulations = this._deltaMetricStorage.collect();
return this._temporalMetricStorage.buildMetrics(collector, this._instrumentDescriptor, accumulations, collectionTime);
}
}
//# sourceMappingURL=SyncMetricStorage.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SyncMetricStorage.js","sourceRoot":"","sources":["../../../src/state/SyncMetricStorage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAIpE;;;;GAIG;AACH,MAAM,OAAO,iBACX,SAAQ,aAAa;IAMrB,YACE,oBAA0C,EAC1C,UAAyB,EACjB,oBAAyC,EACjD,gBAAyC,EACjC,4BAAqC;QAE7C,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAJpB,yBAAoB,GAApB,oBAAoB,CAAqB;QAEzC,iCAA4B,GAA5B,4BAA4B,CAAS;QAG7C,IAAI,CAAC,mBAAmB,GAAG,IAAI,oBAAoB,CACjD,UAAU,EACV,IAAI,CAAC,4BAA4B,CAClC,CAAC;QACF,IAAI,CAAC,sBAAsB,GAAG,IAAI,uBAAuB,CACvD,UAAU,EACV,gBAAgB,CACjB,CAAC;IACJ,CAAC;IAED,MAAM,CACJ,KAAa,EACb,UAAsB,EACtB,OAAgB,EAChB,UAAkB;QAElB,UAAU,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACpE,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAC1E,CAAC;IAED;;;;;OAKG;IACH,OAAO,CACL,SAAgC,EAChC,cAAsB;QAEtB,MAAM,aAAa,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;QAEzD,OAAO,IAAI,CAAC,sBAAsB,CAAC,YAAY,CAC7C,SAAS,EACT,IAAI,CAAC,qBAAqB,EAC1B,aAAa,EACb,cAAc,CACf,CAAC;IACJ,CAAC;CACF","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Context, HrTime, Attributes } from '@opentelemetry/api';\nimport { WritableMetricStorage } from './WritableMetricStorage';\nimport { Accumulation, Aggregator } from '../aggregator/types';\nimport { InstrumentDescriptor } from '../InstrumentDescriptor';\nimport { AttributesProcessor } from '../view/AttributesProcessor';\nimport { MetricStorage } from './MetricStorage';\nimport { MetricData } from '../export/MetricData';\nimport { DeltaMetricProcessor } from './DeltaMetricProcessor';\nimport { TemporalMetricProcessor } from './TemporalMetricProcessor';\nimport { Maybe } from '../utils';\nimport { MetricCollectorHandle } from './MetricCollector';\n\n/**\n * Internal interface.\n *\n * Stores and aggregates {@link MetricData} for synchronous instruments.\n */\nexport class SyncMetricStorage<T extends Maybe<Accumulation>>\n extends MetricStorage\n implements WritableMetricStorage\n{\n private _deltaMetricStorage: DeltaMetricProcessor<T>;\n private _temporalMetricStorage: TemporalMetricProcessor<T>;\n\n constructor(\n instrumentDescriptor: InstrumentDescriptor,\n aggregator: Aggregator<T>,\n private _attributesProcessor: AttributesProcessor,\n collectorHandles: MetricCollectorHandle[],\n private _aggregationCardinalityLimit?: number\n ) {\n super(instrumentDescriptor);\n this._deltaMetricStorage = new DeltaMetricProcessor(\n aggregator,\n this._aggregationCardinalityLimit\n );\n this._temporalMetricStorage = new TemporalMetricProcessor(\n aggregator,\n collectorHandles\n );\n }\n\n record(\n value: number,\n attributes: Attributes,\n context: Context,\n recordTime: HrTime\n ) {\n attributes = this._attributesProcessor.process(attributes, context);\n this._deltaMetricStorage.record(value, attributes, context, recordTime);\n }\n\n /**\n * Collects the metrics from this storage.\n *\n * Note: This is a stateful operation and may reset any interval-related\n * state for the MetricCollector.\n */\n collect(\n collector: MetricCollectorHandle,\n collectionTime: HrTime\n ): Maybe<MetricData> {\n const accumulations = this._deltaMetricStorage.collect();\n\n return this._temporalMetricStorage.buildMetrics(\n collector,\n this._instrumentDescriptor,\n accumulations,\n collectionTime\n );\n }\n}\n"]}

View File

@@ -0,0 +1,38 @@
import { HrTime } from '@opentelemetry/api';
import { Accumulation, Aggregator } from '../aggregator/types';
import { MetricData } from '../export/MetricData';
import { InstrumentDescriptor } from '../InstrumentDescriptor';
import { Maybe } from '../utils';
import { MetricCollectorHandle } from './MetricCollector';
import { AttributeHashMap } from './HashMap';
/**
* Internal interface.
*
* Provides unique reporting for each collector. Allows synchronous collection
* of metrics and reports given temporality values.
*/
export declare class TemporalMetricProcessor<T extends Maybe<Accumulation>> {
private _aggregator;
private _unreportedAccumulations;
private _reportHistory;
constructor(_aggregator: Aggregator<T>, collectorHandles: MetricCollectorHandle[]);
/**
* Builds the {@link MetricData} streams to report against a specific MetricCollector.
* @param collector The information of the MetricCollector.
* @param collectors The registered collectors.
* @param instrumentDescriptor The instrumentation descriptor that these metrics generated with.
* @param currentAccumulations The current accumulation of metric data from instruments.
* @param collectionTime The current collection timestamp.
* @returns The {@link MetricData} points or `null`.
*/
buildMetrics(collector: MetricCollectorHandle, instrumentDescriptor: InstrumentDescriptor, currentAccumulations: AttributeHashMap<T>, collectionTime: HrTime): Maybe<MetricData>;
private _stashAccumulations;
private _getMergedUnreportedAccumulations;
static merge<T extends Maybe<Accumulation>>(last: AttributeHashMap<T>, current: AttributeHashMap<T>, aggregator: Aggregator<T>): AttributeHashMap<T>;
/**
* Calibrate the reported metric streams' startTime to lastCollectionTime. Leaves
* the new stream to be the initial observation time unchanged.
*/
static calibrateStartTime<T extends Maybe<Accumulation>>(last: AttributeHashMap<T>, current: AttributeHashMap<T>, lastCollectionTime: HrTime): AttributeHashMap<T>;
}
//# sourceMappingURL=TemporalMetricProcessor.d.ts.map

View File

@@ -0,0 +1,151 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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 { AggregationTemporality } from '../export/AggregationTemporality';
import { AttributeHashMap } from './HashMap';
/**
* Internal interface.
*
* Provides unique reporting for each collector. Allows synchronous collection
* of metrics and reports given temporality values.
*/
export class TemporalMetricProcessor {
constructor(_aggregator, collectorHandles) {
this._aggregator = _aggregator;
this._unreportedAccumulations = new Map();
this._reportHistory = new Map();
collectorHandles.forEach(handle => {
this._unreportedAccumulations.set(handle, []);
});
}
/**
* Builds the {@link MetricData} streams to report against a specific MetricCollector.
* @param collector The information of the MetricCollector.
* @param collectors The registered collectors.
* @param instrumentDescriptor The instrumentation descriptor that these metrics generated with.
* @param currentAccumulations The current accumulation of metric data from instruments.
* @param collectionTime The current collection timestamp.
* @returns The {@link MetricData} points or `null`.
*/
buildMetrics(collector, instrumentDescriptor, currentAccumulations, collectionTime) {
this._stashAccumulations(currentAccumulations);
const unreportedAccumulations = this._getMergedUnreportedAccumulations(collector);
let result = unreportedAccumulations;
let aggregationTemporality;
// Check our last report time.
if (this._reportHistory.has(collector)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const last = this._reportHistory.get(collector);
const lastCollectionTime = last.collectionTime;
aggregationTemporality = last.aggregationTemporality;
// Use aggregation temporality + instrument to determine if we do a merge or a diff of
// previous. We have the following four scenarios:
// 1. Cumulative Aggregation (temporality) + Delta recording (sync instrument).
// Here we merge with our last record to get a cumulative aggregation.
// 2. Cumulative Aggregation + Cumulative recording (async instrument).
// Cumulative records are converted to delta recording with DeltaMetricProcessor.
// Here we merge with our last record to get a cumulative aggregation.
// 3. Delta Aggregation + Delta recording
// Calibrate the startTime of metric streams to be the reader's lastCollectionTime.
// 4. Delta Aggregation + Cumulative recording.
// Cumulative records are converted to delta recording with DeltaMetricProcessor.
// Calibrate the startTime of metric streams to be the reader's lastCollectionTime.
if (aggregationTemporality === AggregationTemporality.CUMULATIVE) {
// We need to make sure the current delta recording gets merged into the previous cumulative
// for the next cumulative recording.
result = TemporalMetricProcessor.merge(last.accumulations, unreportedAccumulations, this._aggregator);
}
else {
result = TemporalMetricProcessor.calibrateStartTime(last.accumulations, unreportedAccumulations, lastCollectionTime);
}
}
else {
// Call into user code to select aggregation temporality for the instrument.
aggregationTemporality = collector.selectAggregationTemporality(instrumentDescriptor.type);
}
// Update last reported (cumulative) accumulation.
this._reportHistory.set(collector, {
accumulations: result,
collectionTime,
aggregationTemporality,
});
const accumulationRecords = AttributesMapToAccumulationRecords(result);
// do not convert to metric data if there is nothing to convert.
if (accumulationRecords.length === 0) {
return undefined;
}
return this._aggregator.toMetricData(instrumentDescriptor, aggregationTemporality, accumulationRecords,
/* endTime */ collectionTime);
}
_stashAccumulations(currentAccumulation) {
const registeredCollectors = this._unreportedAccumulations.keys();
for (const collector of registeredCollectors) {
let stash = this._unreportedAccumulations.get(collector);
if (stash === undefined) {
stash = [];
this._unreportedAccumulations.set(collector, stash);
}
stash.push(currentAccumulation);
}
}
_getMergedUnreportedAccumulations(collector) {
let result = new AttributeHashMap();
const unreportedList = this._unreportedAccumulations.get(collector);
this._unreportedAccumulations.set(collector, []);
if (unreportedList === undefined) {
return result;
}
for (const it of unreportedList) {
result = TemporalMetricProcessor.merge(result, it, this._aggregator);
}
return result;
}
static merge(last, current, aggregator) {
const result = last;
const iterator = current.entries();
let next = iterator.next();
while (next.done !== true) {
const [key, record, hash] = next.value;
if (last.has(key, hash)) {
const lastAccumulation = last.get(key, hash);
// last.has() returned true, lastAccumulation is present.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const accumulation = aggregator.merge(lastAccumulation, record);
result.set(key, accumulation, hash);
}
else {
result.set(key, record, hash);
}
next = iterator.next();
}
return result;
}
/**
* Calibrate the reported metric streams' startTime to lastCollectionTime. Leaves
* the new stream to be the initial observation time unchanged.
*/
static calibrateStartTime(last, current, lastCollectionTime) {
for (const [key, hash] of last.keys()) {
const currentAccumulation = current.get(key, hash);
currentAccumulation === null || currentAccumulation === void 0 ? void 0 : currentAccumulation.setStartTime(lastCollectionTime);
}
return current;
}
}
// TypeScript complains about converting 3 elements tuple to AccumulationRecord<T>.
function AttributesMapToAccumulationRecords(map) {
return Array.from(map.entries());
}
//# sourceMappingURL=TemporalMetricProcessor.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,23 @@
import { Context, HrTime, Attributes } from '@opentelemetry/api';
import { AttributeHashMap } from './HashMap';
/**
* Internal interface. Stores measurements and allows synchronous writes of
* measurements.
*
* An interface representing SyncMetricStorage with type parameters removed.
*/
export interface WritableMetricStorage {
/** Records a measurement. */
record(value: number, attributes: Attributes, context: Context, recordTime: HrTime): void;
}
/**
* Internal interface. Stores measurements and allows asynchronous writes of
* measurements.
*
* An interface representing AsyncMetricStorage with type parameters removed.
*/
export interface AsyncWritableMetricStorage {
/** Records a batch of measurements. */
record(measurements: AttributeHashMap<number>, observationTime: HrTime): void;
}
//# sourceMappingURL=WritableMetricStorage.d.ts.map

View File

@@ -0,0 +1,17 @@
/*
* Copyright The OpenTelemetry 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
*
* https://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.
*/
export {};
//# sourceMappingURL=WritableMetricStorage.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"WritableMetricStorage.js","sourceRoot":"","sources":["../../../src/state/WritableMetricStorage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Context, HrTime, Attributes } from '@opentelemetry/api';\nimport { AttributeHashMap } from './HashMap';\n\n/**\n * Internal interface. Stores measurements and allows synchronous writes of\n * measurements.\n *\n * An interface representing SyncMetricStorage with type parameters removed.\n */\nexport interface WritableMetricStorage {\n /** Records a measurement. */\n record(\n value: number,\n attributes: Attributes,\n context: Context,\n recordTime: HrTime\n ): void;\n}\n\n/**\n * Internal interface. Stores measurements and allows asynchronous writes of\n * measurements.\n *\n * An interface representing AsyncMetricStorage with type parameters removed.\n */\nexport interface AsyncWritableMetricStorage {\n /** Records a batch of measurements. */\n record(measurements: AttributeHashMap<number>, observationTime: HrTime): void;\n}\n"]}