o11y 240.8.0 → 240.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -76,7 +76,7 @@ var UploadMode;
76
76
  UploadMode[UploadMode["noUpload"] = 2] = "noUpload";
77
77
  })(UploadMode || (UploadMode = {}));
78
78
 
79
- const version='240.11.0';
79
+ const version='240.15.1';
80
80
 
81
81
  const coreEnvelopeKey = 'o11y';
82
82
  class CoreEnvelopeBuilder {
@@ -1 +1 @@
1
- {"version":3,"file":"collectors.js","sources":["../../../../src/collectors/protobuf-util.ts","../../../../src/collectors/core-collector/UploadMode.ts","../../../../../../node_modules/o11y_schema/version/version.js","../../../../src/collectors/core-collector/CoreEnvelopeBuilder.ts","../../../../src/collectors/core-collector/CoreCollector.ts","../../../../src/collectors/hybrid-collector/HybridCollector.ts"],"sourcesContent":["import { Message, Root, Type } from 'protobufjs';\n\nimport { LogMeta, Schema, SchematizedPayload } from '../interfaces';\nimport { EncodedSchematizedPayload } from './EncodedSchematizedPayload';\nimport { SchematizedData, schemaUtil, utility } from 'o11y/shared';\nimport { LogMessage } from './core-collector/interfaces/LogMessage';\n\nclass ProtobufUtil {\n private readonly _typeStore = new Map<string, Type>();\n\n public getSchemaType(schema: Schema): Type {\n utility.requireArgument(schema, 'schema');\n const schemaPath = schemaUtil.getSchemaId(schema);\n let type = this._typeStore.get(schemaPath);\n\n if (!type) {\n // Lazy add to the type store\n const schemaInstance = Root.fromJSON(schema.pbjsSchema);\n // this will throw if it can't find it\n type = schemaInstance.lookupType(schemaPath);\n this._typeStore.set(schemaPath, type);\n }\n\n return type;\n }\n\n public validate(schema: Schema, data: SchematizedData): Type {\n utility.requireArgument(schema, 'schema');\n utility.requireArgument(data, 'data');\n const type: Type = this.getSchemaType(schema);\n\n const errorText = type.verify(data);\n if (errorText) {\n throw new Error(`Data is invalid for ${type.fullName}: ${errorText}`);\n }\n return type;\n }\n\n public encode(schema: Schema, data: SchematizedData): Uint8Array {\n const type: Type = this.validate(schema, data);\n const message: Message = type.fromObject(data);\n const encoded: Uint8Array = type.encode(message).finish();\n return encoded;\n }\n\n public encodePayload(rawPayload: SchematizedPayload): EncodedSchematizedPayload {\n if (rawPayload && rawPayload.schema && rawPayload.payload) {\n return {\n schemaName: schemaUtil.getSchemaId(rawPayload.schema),\n payload: this.encode(rawPayload.schema, rawPayload.payload)\n };\n }\n return undefined;\n }\n\n // This method generates a LogMessage (used in the CoreEnvelope) from the provided arguments.\n public getLogMessage(schema: Schema, data: SchematizedData, logMeta: LogMeta): LogMessage {\n return {\n timestamp: logMeta.timestamp,\n data: this.encode(schema, data),\n age: utility.getAge(logMeta.timestamp),\n rootId: logMeta.rootId,\n seq: logMeta.sequence,\n sseq: logMeta.schemaSequence,\n loggerName: logMeta.loggerName,\n pagePayload: this.encodePayload(logMeta.pagePayload),\n loggerAppName: logMeta.loggerAppName,\n connectionType: logMeta.connectionType,\n appPayload: this.encodePayload(logMeta.appPayload)\n };\n }\n}\n\nexport const protobufUtil = new ProtobufUtil();\n","export enum UploadMode {\n fetchBinary, // application/octet-stream\n fetchFile, // multipart/form-data\n noUpload\n}\n","export const version='240.11.0'","import { BucketMetric, Metric } from '../../interfaces';\nimport { MetricsTags, utility } from 'o11y/shared';\nimport { CoreEnvelope } from './interfaces/CoreEnvelope';\nimport { LogMessage } from './interfaces/LogMessage';\nimport { MessageBundle } from './interfaces/MessageBundle';\nimport { StaticAttributes } from './interfaces/StaticAttributes';\nimport { BucketHistogram } from '../metrics/BucketHistogram';\nimport { UpCounter } from '../metrics/UpCounter';\nimport { ValueRecorder } from '../metrics/ValueRecorder';\nimport { version as schemaVersion } from 'o11y_schema/version';\nimport { MetricTag } from '../metrics/MetricTag';\n\nexport const coreEnvelopeKey = 'o11y';\nexport class CoreEnvelopeBuilder {\n private _envelope: CoreEnvelope;\n\n constructor() {\n this._envelope = {\n diagnostics: {\n key: coreEnvelopeKey,\n generatedTimestamp: undefined,\n bundleCount: 0,\n bucketHistogramCount: 0,\n upCounterCount: 0,\n valueRecorderCount: 0,\n schemaVersion\n },\n bundles: [] as MessageBundle[],\n metrics: {\n bucketHistograms: [] as BucketHistogram[],\n upCounters: [] as UpCounter[],\n valueRecorders: [] as ValueRecorder[]\n },\n staticAttributes: {}\n };\n }\n\n withStaticAttributes(staticAttributes: StaticAttributes): CoreEnvelopeBuilder {\n this._envelope.staticAttributes = staticAttributes;\n return this;\n }\n\n withLogs(schemaName: string, logs: LogMessage[]): CoreEnvelopeBuilder {\n let msgBundle: MessageBundle = this._envelope.bundles.find(\n (bundle) => bundle.schemaName === schemaName\n );\n\n if (msgBundle) {\n for (const log of logs) {\n msgBundle.messages.push(log);\n }\n } else {\n msgBundle = {\n schemaName: schemaName,\n messages: logs\n };\n this._envelope.bundles.push(msgBundle);\n }\n this._envelope.diagnostics.bundleCount = this._envelope.bundles.length;\n return this;\n }\n\n private static _getMetricTags<T>(metric: Metric<T>): MetricTag[] {\n const tags: MetricsTags = metric.getTags();\n if (tags) {\n return Object.entries(tags).map((entry) => {\n const mt: MetricTag = {\n name: entry[0],\n value: entry[1].toString()\n };\n return mt;\n });\n }\n return undefined;\n }\n\n static getUpCounters(metrics: Metric<number>[], reset = true): UpCounter[] {\n return metrics.map((metric) => {\n const data: UpCounter = {\n name: metric.getName(),\n createdTimestamp: metric.getCreatedOn(),\n lastUpdatedTimestamp: metric.getLastUpdatedOn(),\n value: metric.getData(),\n ownerName: metric.getOwnerName(),\n ownerAppName: metric.getOwnerAppName(),\n tags: this._getMetricTags(metric)\n };\n if (reset) {\n metric.reset();\n }\n return data;\n });\n }\n\n static getValueRecorders(metrics: Metric<number[]>[], reset = true): ValueRecorder[] {\n return metrics.map((metric) => {\n const data: ValueRecorder = {\n name: metric.getName(),\n createdTimestamp: metric.getCreatedOn(),\n lastUpdatedTimestamp: metric.getLastUpdatedOn(),\n values: metric.getData(),\n ownerName: metric.getOwnerName(),\n ownerAppName: metric.getOwnerAppName(),\n tags: this._getMetricTags(metric)\n };\n if (reset) {\n metric.reset();\n }\n return data;\n });\n }\n\n static getBucketHistograms(metrics: BucketMetric<number[]>[], reset = true): BucketHistogram[] {\n return metrics.map((metric) => {\n const data: BucketHistogram = {\n name: metric.getName(),\n createdTimestamp: metric.getCreatedOn(),\n lastUpdatedTimestamp: metric.getLastUpdatedOn(),\n values: metric.getData(),\n buckets: metric.getBuckets(),\n ownerName: metric.getOwnerName(),\n ownerAppName: metric.getOwnerAppName(),\n tags: this._getMetricTags(metric)\n };\n if (reset) {\n metric.reset();\n }\n return data;\n });\n }\n\n withUpCounters(upCounters: UpCounter[]): CoreEnvelopeBuilder {\n for (const upCounter of upCounters) {\n this._envelope.metrics.upCounters.push(upCounter);\n }\n this._envelope.diagnostics.upCounterCount = this._envelope.metrics.upCounters.length;\n return this;\n }\n\n withValueRecorders(valueRecorders: ValueRecorder[]): CoreEnvelopeBuilder {\n for (const valueRecorder of valueRecorders) {\n this._envelope.metrics.valueRecorders.push(valueRecorder);\n }\n this._envelope.diagnostics.valueRecorderCount =\n this._envelope.metrics.valueRecorders.length;\n return this;\n }\n\n withBucketHistograms(bucketHistograms: BucketHistogram[]): CoreEnvelopeBuilder {\n for (const bucketHistogram of bucketHistograms) {\n this._envelope.metrics.bucketHistograms.push(bucketHistogram);\n }\n this._envelope.diagnostics.bucketHistogramCount =\n this._envelope.metrics.bucketHistograms.length;\n return this;\n }\n\n build(): CoreEnvelope {\n this._envelope.diagnostics.generatedTimestamp = utility.time().tsNow;\n return this._envelope;\n }\n}\n","import { Root, Type } from 'protobufjs';\nimport { coreEnvelopeSchema } from 'o11y_schema/sf_instrumentation';\n\nimport {\n Environment,\n LogCollector,\n LogMeta,\n MetricsCollector,\n MetricsExtractorMethods,\n Schema\n} from '../../interfaces';\nimport { LazyMapToList, SchematizedData, schemaUtil, utility } from 'o11y/shared';\n\nimport { protobufUtil } from '../protobuf-util';\nimport { UploadMode } from './UploadMode';\nimport { CoreCollectorOptions } from './interfaces/CoreCollectorOptions';\nimport { CoreEnvelope } from './interfaces/CoreEnvelope';\nimport { CoreEnvelopeBuilder } from './CoreEnvelopeBuilder';\nimport { LogMessage } from './interfaces/LogMessage';\nimport { StaticAttributes } from './interfaces/StaticAttributes';\nimport { CoreEnvelopeContents } from './interfaces/CoreEnvelopeContents';\nimport { UploadResult } from './interfaces/UploadResult';\n\nconst defaultMaxUniqueSchemas = 10000;\nconst defaultMaxDelayBeforeUpload = 10000;\nconst defaultMessagesLimit = 10;\nconst defaultMetricsLimit = 10;\nconst defaultFormDataKey = 'telemetry';\nconst defaultUploadMode = UploadMode.fetchBinary;\n\nexport type UploadOptionsCallback = () => RequestInit;\n\nexport class CoreCollector implements LogCollector, MetricsCollector {\n private readonly _messageBuffers: LazyMapToList<Schema, LogMessage>;\n private readonly _coreEnvelopeType: Type;\n private _intervalHandle: NodeJS.Timeout;\n private _metricsExtractors: MetricsExtractorMethods;\n private readonly _staticAttributes: StaticAttributes;\n private _immediateUpload: boolean;\n private readonly _messagesLimit: number = defaultMessagesLimit;\n /*\n Known limitation:\n Unlike _messagesLimit, _metricsLimit is not a strict limit in all cases, as the CoreCollector\n doesn't get notified every time a new metric is added. Instead, it takes metrics into account\n when a message is logged or the upload timer is elapsed. If the _metricsLimit is exceeded \n with no messages logged and upload time not yet elapsed, upload will not occur.\n */\n private readonly _metricsLimit: number = defaultMetricsLimit;\n private readonly _formDataKey: string = defaultFormDataKey;\n private readonly _uploadFailedListener: (ur: UploadResult) => unknown;\n private _uploadInterval: number = defaultMaxDelayBeforeUpload;\n private _uploadEndpoint: string;\n private _uploadMode: UploadMode;\n private readonly _emptySize: number;\n private _messageSize = 0;\n private _uploadOptionsCallback: UploadOptionsCallback;\n\n constructor(\n uploadEndpoint?: string,\n uploadMode?: UploadMode,\n environment?: Environment,\n options?: CoreCollectorOptions\n ) {\n this.uploadEndpoint = uploadEndpoint;\n this.uploadMode = uploadMode == undefined ? defaultUploadMode : uploadMode;\n\n const root = Root.fromJSON(coreEnvelopeSchema.pbjsSchema);\n this._coreEnvelopeType = root.lookupType('CoreEnvelope');\n\n if (environment) {\n this._staticAttributes = {\n appName: environment.appName,\n appVersion: environment.appVersion,\n appExperience: environment.appExperience,\n deviceId: environment.deviceId,\n deviceModel: environment.deviceModel,\n sdkVersion: environment.sdkVersion\n };\n }\n\n let maxUniqueSchemas = defaultMaxUniqueSchemas;\n if (options) {\n const mus: number = options.maxUniqueSchemas;\n if (mus !== undefined) {\n if (typeof mus !== 'number' || !(mus > 0)) {\n throw new Error('options.maxUniqueSchemas, if defined, must be > 0');\n }\n maxUniqueSchemas = mus;\n }\n\n const msglim: number = options.messagesLimit;\n if (msglim !== undefined) {\n if (typeof msglim !== 'number' || !(msglim > 0)) {\n throw new Error('options.messagesLimit, if defined, must be > 0');\n }\n this._messagesLimit = msglim;\n }\n\n const metlim: number = options.metricsLimit;\n if (metlim !== undefined) {\n if (typeof metlim !== 'number' || !(metlim > 0)) {\n throw new Error('options.metricsLimit, if defined, must be > 0');\n }\n this._metricsLimit = metlim;\n }\n\n if (\n utility.requireArgumentIfDefined(\n options.formDataKeyName,\n 'options.formDataKeyName',\n 'string'\n )\n ) {\n this._formDataKey = options.formDataKeyName;\n }\n\n if (\n utility.requireArgumentIfDefined(\n options.uploadFailedListener,\n 'options.uploadFailedListener',\n 'function'\n )\n ) {\n this._uploadFailedListener = options.uploadFailedListener;\n }\n }\n this._messageBuffers = new LazyMapToList<Schema, LogMessage>(maxUniqueSchemas);\n\n this._emptySize = this.getByteSize(1);\n this._restartTimer();\n }\n\n get uploadInterval(): number {\n return this._uploadInterval;\n }\n set uploadInterval(uploadInterval: number) {\n if (uploadInterval === undefined) {\n uploadInterval = defaultMaxDelayBeforeUpload;\n }\n if (typeof uploadInterval !== 'number' || !(uploadInterval > 0)) {\n throw new Error('uploadInterval, if defined, must be > 0');\n }\n if (uploadInterval !== this._uploadInterval) {\n this._uploadInterval = uploadInterval;\n // Now that the interval has changed, restart the timer\n this._restartTimer();\n }\n }\n\n get uploadEndpoint(): string {\n return this._uploadEndpoint;\n }\n set uploadEndpoint(uploadEndpoint: string) {\n utility.requireArgumentIfDefined(uploadEndpoint, 'uploadEndpoint', 'string');\n this._uploadEndpoint = uploadEndpoint;\n }\n\n get uploadOptionsCallback(): UploadOptionsCallback {\n return this._uploadOptionsCallback;\n }\n set uploadOptionsCallback(uploadOptionsCallback: UploadOptionsCallback) {\n utility.requireArgumentIfDefined(\n uploadOptionsCallback,\n 'uploadOptionsCallback',\n 'function'\n );\n\n this._uploadOptionsCallback = uploadOptionsCallback;\n }\n\n get uploadMode(): UploadMode {\n return this._uploadMode;\n }\n set uploadMode(uploadMode: UploadMode) {\n utility.requireArgumentIfDefined(uploadMode, 'uploadMode', 'number');\n if (uploadMode === undefined) {\n uploadMode = defaultUploadMode;\n }\n if (!(uploadMode in UploadMode)) {\n throw new Error(`Unsupported upload mode: ${uploadMode}`);\n }\n this._uploadMode = uploadMode;\n }\n\n // Note: If making changes to this method, please locally test using SizeEstimation.test.js\n getByteSize(accuracy?: number): number {\n // This method provides an estimate.\n // Accuracy is specified as 1 = most accurate\n return accuracy >= 1\n ? this._buildProtoEncodedCoreEnvelope(false).byteLength\n : accuracy >= 0.5\n ? this._emptySize + this._messageSize + this.metricsCount * 8\n : this._emptySize + this._messageSize;\n }\n\n private _stopTimer(): void {\n if (this._intervalHandle !== undefined) {\n clearInterval(this._intervalHandle);\n this._intervalHandle = undefined;\n }\n }\n\n private _restartTimer(): void {\n this._stopTimer();\n this._intervalHandle = setInterval(() => {\n if (this.hasData) {\n this._upload();\n }\n }, this._uploadInterval);\n }\n\n // This method is implementing the LogCollector interface, but needs to return (not swallow)\n // the async result in order for direct call to it from test to handle failure cases properly.\n async collect(schema: Schema, data: SchematizedData, logMeta: LogMeta): Promise<UploadResult> {\n if (schemaUtil.isInternal(schema) && data.userPayload) {\n data.userPayload = protobufUtil.encodePayload(data.userPayload);\n }\n const msg: LogMessage = protobufUtil.getLogMessage(schema, data, logMeta);\n\n if (!this._messageBuffers.push(schema, msg)) {\n throw new Error(`Buffer is full. Refusing schemaId ${schemaUtil.getSchemaId(schema)}`);\n }\n // Get an estimate\n this._messageSize += utility.estimateObjectSize(msg);\n if (this._shouldUpload()) {\n return this._upload();\n }\n return undefined;\n }\n\n private _shouldUpload(): boolean {\n return (\n (this._immediateUpload && this.hasData) ||\n this.messagesCount >= this._messagesLimit ||\n this.metricsCount >= this._metricsLimit\n );\n }\n\n private async _upload(userInitiated?: boolean): Promise<UploadResult> {\n this._restartTimer();\n if (!this._uploadEndpoint || this._uploadMode === UploadMode.noUpload) {\n return undefined;\n }\n\n const contents: CoreEnvelopeContents = this._getContentsOfCoreEnvelope(true);\n return this._uploadContents(contents, userInitiated);\n }\n\n private async _uploadContents(\n contents: CoreEnvelopeContents,\n userInitiated: boolean\n ): Promise<UploadResult> {\n const coreEnvelope: Uint8Array = this._buildProtoEncodedCoreEnvelopeFrom(contents);\n\n let requestInit: RequestInit;\n switch (this._uploadMode) {\n case UploadMode.fetchBinary:\n requestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/octet-stream'\n },\n body: coreEnvelope\n };\n break;\n case UploadMode.fetchFile:\n const formData = new FormData();\n formData.append(this._formDataKey, new Blob([coreEnvelope]));\n // Per [this article](https://muffinman.io/uploading-files-using-fetch-multipart-form-data/)\n // make sure not to set the Content-Type header.\n // The browser will set it for you, including the boundary parameter.\n requestInit = {\n method: 'POST',\n body: formData\n };\n break;\n }\n\n const ur: UploadResult = {\n envelopeContents: contents\n };\n try {\n if (this._uploadOptionsCallback) {\n const options: RequestInit = this._uploadOptionsCallback() || {};\n if (options) {\n if (options.headers && requestInit.headers) {\n // According to lim.dom.d.ts:\n // type HeadersInit = string[][] | Record<string, string> | Headers;\n if (options.headers instanceof Headers) {\n for (const key in requestInit.headers) {\n if (\n Object.prototype.hasOwnProperty.call(requestInit.headers, key)\n ) {\n options.headers.set(\n key,\n (requestInit.headers as Record<string, string>)[key]\n );\n }\n }\n } else if (Array.isArray(options.headers)) {\n // This doesn't seem valid according to https://developer.mozilla.org/en-US/docs/Web/API/fetch\n throw new Error('Headers as array is not supported.');\n } else {\n Object.assign(options.headers, requestInit.headers);\n }\n }\n options.method = requestInit.method;\n options.body = requestInit.body;\n requestInit = options;\n }\n }\n\n ur.response = await fetch(this._uploadEndpoint, requestInit);\n // fetch only throws on network errors, not HTTP errors, so handle that here\n if (!ur.response.ok) {\n throw new Error('HTTP Not OK');\n }\n return ur;\n } catch (err) {\n ur.error = err;\n if (!userInitiated && this._uploadFailedListener) {\n try {\n this._uploadFailedListener(ur);\n } catch {}\n }\n throw ur;\n }\n }\n\n private _checkUploadState(): void {\n if (this._uploadEndpoint === undefined) {\n throw new Error('Upload endpoint is unset');\n }\n if (this._uploadMode === UploadMode.noUpload) {\n throw new Error('Upload mode is unset');\n }\n }\n\n // User initiated method\n public async upload(contents?: CoreEnvelopeContents): Promise<UploadResult> {\n this._checkUploadState();\n if (utility.requireArgumentIfDefined(contents, 'contents', 'object')) {\n return this._uploadContents(contents, true);\n }\n\n return this.hasData ? this._upload(true) : undefined;\n }\n\n get hasData(): boolean {\n return this.messagesCount > 0 || this.metricsCount > 0;\n }\n\n get messagesCount(): number {\n return this._messageBuffers.totalItemCount;\n }\n\n get metricsCount(): number {\n let count = 0;\n\n if (this._metricsExtractors) {\n let metrics: unknown[] = this._metricsExtractors.getAllUpCounters();\n count += (metrics && metrics.length) || 0;\n metrics = this._metricsExtractors.getAllValueRecorders();\n count += (metrics && metrics.length) || 0;\n metrics = this._metricsExtractors.getAllBucketHistograms();\n count += (metrics && metrics.length) || 0;\n }\n\n return count;\n }\n\n getProtoEncodedCoreEnvelope(): Uint8Array {\n return this._buildProtoEncodedCoreEnvelope(true);\n }\n\n getContentsOfCoreEnvelope(): CoreEnvelopeContents {\n return this._getContentsOfCoreEnvelope(true);\n }\n\n private _getContentsOfCoreEnvelope(extract: boolean): CoreEnvelopeContents {\n // 1. extract=true is for most use cases.\n // 2. extract=false is for peeking into the contents without affecting them\n // (i.e. messages are kept in the buffers and metrics are not reset.)\n // Message arrays are references to the originals and should be handled carefully.\n\n const contents: CoreEnvelopeContents = {\n staticAttributes: this._staticAttributes,\n messages: this._messageBuffers.getAllMessages(extract)\n };\n\n if (this._metricsExtractors) {\n contents.upCounters = CoreEnvelopeBuilder.getUpCounters(\n this._metricsExtractors.getAllUpCounters(),\n extract\n );\n contents.valueRecorders = CoreEnvelopeBuilder.getValueRecorders(\n this._metricsExtractors.getAllValueRecorders(),\n extract\n );\n contents.bucketHistograms = CoreEnvelopeBuilder.getBucketHistograms(\n this._metricsExtractors.getAllBucketHistograms(),\n extract\n );\n }\n\n if (extract) {\n this._messageSize = 0;\n }\n return contents;\n }\n\n private _buildProtoEncodedCoreEnvelope(extract: boolean): Uint8Array {\n const contents: CoreEnvelopeContents = this._getContentsOfCoreEnvelope(extract);\n return this._buildProtoEncodedCoreEnvelopeFrom(contents);\n }\n\n private _buildProtoEncodedCoreEnvelopeFrom(contents?: CoreEnvelopeContents): Uint8Array {\n const builder = new CoreEnvelopeBuilder();\n\n if (contents.staticAttributes) {\n builder.withStaticAttributes(contents.staticAttributes);\n }\n if (contents.messages) {\n contents.messages.forEach((logs: LogMessage[], schema: Schema) => {\n builder.withLogs(schemaUtil.getSchemaId(schema), logs);\n });\n }\n if (contents.upCounters) {\n builder.withUpCounters(contents.upCounters);\n }\n if (contents.valueRecorders) {\n builder.withValueRecorders(contents.valueRecorders);\n }\n if (contents.bucketHistograms) {\n builder.withBucketHistograms(contents.bucketHistograms);\n }\n\n return this._encodeCoreEnvelope(builder.build());\n }\n\n private _encodeCoreEnvelope(coreEnvelope: CoreEnvelope): Uint8Array {\n const errorMessage = this._coreEnvelopeType.verify(coreEnvelope);\n if (errorMessage) {\n throw new Error(`Invalid CoreEnvelope: ${errorMessage}`);\n }\n\n const encodedCoreEnvelope = this._coreEnvelopeType.encode(coreEnvelope).finish();\n return encodedCoreEnvelope;\n }\n\n receiveMetricsExtractors(metricsExtractors: MetricsExtractorMethods): void {\n this._metricsExtractors = metricsExtractors;\n }\n}\n","import {\n BucketMetric,\n LogCollector,\n LogMeta,\n Metric,\n MetricsCollector,\n MetricsExtractorMethods,\n Schema\n} from '../../interfaces';\nimport { SchematizedData, MetricsTags, schemaUtil, utility } from 'o11y/shared';\nimport { protobufUtil } from '../protobuf-util';\nimport { LogMessage } from '../core-collector/interfaces/LogMessage';\nimport { EncodedSchematizedPayload } from '../EncodedSchematizedPayload';\nimport { MetricTag } from '../metrics/MetricTag';\nimport { UpCounter } from '../metrics/UpCounter';\nimport { ValueRecorder } from '../metrics/ValueRecorder';\nimport { BucketHistogram } from '../metrics/BucketHistogram';\nimport { Metrics } from '../metrics/Metrics';\n\nconst metricsCollectionMilliseconds = 30000;\n\n// The observability plugin expects encoded payloads, so can't use LogMeta as-is.\ninterface LogMetaObservability {\n timestamp: number;\n rootId: string;\n sequence: number;\n loggerName: string;\n pagePayload: EncodedSchematizedPayload;\n loggerAppName: string;\n connectionType: string;\n appPayload: EncodedSchematizedPayload;\n}\n\n// The following interface is expected to be fulfilled by the\n// observability plugin in Lightning SDK.\ndeclare type NimbusObservabilityPlugin = {\n // Called to send a collected message to native for handling\n log: (schema: string, encodedMessage: Uint8Array, logMeta: LogMetaObservability) => void;\n\n // Called to send metrics to native for handling\n logMetrics: (metrics: Metrics) => void;\n\n // Called to listen for root activity changes in native.\n //\n // The startListener is called with the id of the root activity when an activity is started\n // The stopListener is called when a root activity is stopped\n addRootActivityListeners: (\n startListener: (activityInfo: { id: string }) => void,\n stopListener: () => void\n ) => void;\n\n // Called to inform native that the web view has detected an idle state.\n idleDetected: (timestamp: number) => void;\n};\n\n// The `HybridCollector` uses nimbus to send log data immediately across\n// to be handled by the native observability library.\nexport class HybridCollector implements LogCollector, MetricsCollector {\n private readonly _observability: NimbusObservabilityPlugin;\n private _metricsExtractors: MetricsExtractorMethods;\n\n constructor() {\n if (typeof __nimbus === 'undefined') {\n throw new Error('Nimbus is unavailable');\n }\n if (!__nimbus.plugins || !__nimbus.plugins.observability) {\n throw new Error('Observability plugin not found in Nimbus plugins');\n }\n this._observability = __nimbus.plugins.observability as NimbusObservabilityPlugin;\n setInterval(() => {\n this._collectMetrics();\n }, metricsCollectionMilliseconds);\n }\n\n collect(schema: Schema, data: SchematizedData, logMeta: LogMeta): void {\n if (schemaUtil.isInternal(schema) && data.userPayload) {\n data.userPayload = protobufUtil.encodePayload(data.userPayload);\n }\n const logMessage: LogMessage = protobufUtil.getLogMessage(schema, data, logMeta);\n const logMetaObs: LogMetaObservability = {\n timestamp: logMeta.timestamp,\n rootId: logMeta.rootId,\n sequence: logMeta.sequence,\n loggerName: logMeta.loggerName,\n pagePayload: logMessage.pagePayload,\n loggerAppName: logMeta.loggerAppName,\n connectionType: logMeta.connectionType,\n appPayload: logMessage.appPayload\n };\n this._observability.log(schemaUtil.getSchemaId(schema), logMessage.data, logMetaObs);\n }\n\n receiveMetricsExtractors(metricsExtractors: MetricsExtractorMethods): void {\n this._metricsExtractors = metricsExtractors;\n }\n\n // An app can call this method to listen for root activities that start and stop\n // on the native side, in order to associate web activities with the same root id.\n addRootActivityListeners(\n activityStarted: (info: { id: string }) => void,\n activityEnded: () => void\n ): void {\n utility.requireArgument(activityStarted, 'activityStarted', 'function');\n utility.requireArgument(activityEnded, 'activityEnded', 'function');\n\n this._observability.addRootActivityListeners(activityStarted, activityEnded);\n }\n\n // An app should call this method when it detects idle in the web view in order\n // to inform the native app of the idle state.\n notifyIdleDetected(timestamp: number): void {\n this._observability.idleDetected(timestamp);\n }\n\n private _collectMetrics(): void {\n if (this._metricsExtractors) {\n const upCounters: Metric<number>[] = this._metricsExtractors.getAllUpCounters();\n const valueRecorders: Metric<number[]>[] =\n this._metricsExtractors.getAllValueRecorders();\n const bucketHistograms: BucketMetric<number[]>[] =\n this._metricsExtractors.getAllBucketHistograms();\n const recorders: ValueRecorder[] = [];\n const counters: UpCounter[] = [];\n const histograms: BucketHistogram[] = [];\n\n for (const valueRecorder of valueRecorders) {\n const vr: ValueRecorder = {\n name: valueRecorder.getName(),\n createdTimestamp: valueRecorder.getCreatedOn(),\n lastUpdatedTimestamp: valueRecorder.getLastUpdatedOn(),\n values: valueRecorder.getData(),\n ownerName: valueRecorder.getOwnerName(),\n ownerAppName: valueRecorder.getOwnerAppName(),\n tags: this._getMetricTags(valueRecorder)\n };\n recorders.push(vr);\n valueRecorder.reset();\n }\n\n for (const upCounter of upCounters) {\n const uc: UpCounter = {\n name: upCounter.getName(),\n createdTimestamp: upCounter.getCreatedOn(),\n lastUpdatedTimestamp: upCounter.getLastUpdatedOn(),\n value: upCounter.getData(),\n ownerName: upCounter.getOwnerName(),\n ownerAppName: upCounter.getOwnerAppName(),\n tags: this._getMetricTags(upCounter)\n };\n counters.push(uc);\n upCounter.reset();\n }\n\n for (const bucketHistogram of bucketHistograms) {\n const bh: BucketHistogram = {\n name: bucketHistogram.getName(),\n createdTimestamp: bucketHistogram.getCreatedOn(),\n lastUpdatedTimestamp: bucketHistogram.getLastUpdatedOn(),\n values: bucketHistogram.getData(),\n buckets: bucketHistogram.getBuckets(),\n ownerName: bucketHistogram.getOwnerName(),\n ownerAppName: bucketHistogram.getOwnerAppName(),\n tags: this._getMetricTags(bucketHistogram)\n };\n histograms.push(bh);\n bucketHistogram.reset();\n }\n\n if (recorders.length > 0 || counters.length > 0) {\n const metrics: Metrics = {\n upCounters: counters,\n valueRecorders: recorders,\n bucketHistograms: histograms\n };\n this._observability.logMetrics(metrics);\n }\n }\n }\n\n private _getMetricTags<T>(metric: Metric<T>): MetricTag[] {\n const metricsTags: MetricsTags = metric.getTags();\n\n if (metricsTags) {\n return Object.entries(metricsTags).map((entry) => {\n const mt: MetricTag = {\n name: entry[0],\n value: entry[1].toString()\n };\n return mt;\n });\n }\n return [];\n }\n}\n"],"names":["schemaVersion"],"mappings":"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"}
1
+ {"version":3,"file":"collectors.js","sources":["../../../../src/collectors/protobuf-util.ts","../../../../src/collectors/core-collector/UploadMode.ts","../../../../../../node_modules/o11y_schema/version/version.js","../../../../src/collectors/core-collector/CoreEnvelopeBuilder.ts","../../../../src/collectors/core-collector/CoreCollector.ts","../../../../src/collectors/hybrid-collector/HybridCollector.ts"],"sourcesContent":["import { Message, Root, Type } from 'protobufjs';\n\nimport { LogMeta, Schema, SchematizedPayload } from '../interfaces';\nimport { EncodedSchematizedPayload } from './EncodedSchematizedPayload';\nimport { SchematizedData, schemaUtil, utility } from 'o11y/shared';\nimport { LogMessage } from './core-collector/interfaces/LogMessage';\n\nclass ProtobufUtil {\n private readonly _typeStore = new Map<string, Type>();\n\n public getSchemaType(schema: Schema): Type {\n utility.requireArgument(schema, 'schema');\n const schemaPath = schemaUtil.getSchemaId(schema);\n let type = this._typeStore.get(schemaPath);\n\n if (!type) {\n // Lazy add to the type store\n const schemaInstance = Root.fromJSON(schema.pbjsSchema);\n // this will throw if it can't find it\n type = schemaInstance.lookupType(schemaPath);\n this._typeStore.set(schemaPath, type);\n }\n\n return type;\n }\n\n public validate(schema: Schema, data: SchematizedData): Type {\n utility.requireArgument(schema, 'schema');\n utility.requireArgument(data, 'data');\n const type: Type = this.getSchemaType(schema);\n\n const errorText = type.verify(data);\n if (errorText) {\n throw new Error(`Data is invalid for ${type.fullName}: ${errorText}`);\n }\n return type;\n }\n\n public encode(schema: Schema, data: SchematizedData): Uint8Array {\n const type: Type = this.validate(schema, data);\n const message: Message = type.fromObject(data);\n const encoded: Uint8Array = type.encode(message).finish();\n return encoded;\n }\n\n public encodePayload(rawPayload: SchematizedPayload): EncodedSchematizedPayload {\n if (rawPayload && rawPayload.schema && rawPayload.payload) {\n return {\n schemaName: schemaUtil.getSchemaId(rawPayload.schema),\n payload: this.encode(rawPayload.schema, rawPayload.payload)\n };\n }\n return undefined;\n }\n\n // This method generates a LogMessage (used in the CoreEnvelope) from the provided arguments.\n public getLogMessage(schema: Schema, data: SchematizedData, logMeta: LogMeta): LogMessage {\n return {\n timestamp: logMeta.timestamp,\n data: this.encode(schema, data),\n age: utility.getAge(logMeta.timestamp),\n rootId: logMeta.rootId,\n seq: logMeta.sequence,\n sseq: logMeta.schemaSequence,\n loggerName: logMeta.loggerName,\n pagePayload: this.encodePayload(logMeta.pagePayload),\n loggerAppName: logMeta.loggerAppName,\n connectionType: logMeta.connectionType,\n appPayload: this.encodePayload(logMeta.appPayload)\n };\n }\n}\n\nexport const protobufUtil = new ProtobufUtil();\n","export enum UploadMode {\n fetchBinary, // application/octet-stream\n fetchFile, // multipart/form-data\n noUpload\n}\n","export const version='240.15.1'","import { BucketMetric, Metric } from '../../interfaces';\nimport { MetricsTags, utility } from 'o11y/shared';\nimport { CoreEnvelope } from './interfaces/CoreEnvelope';\nimport { LogMessage } from './interfaces/LogMessage';\nimport { MessageBundle } from './interfaces/MessageBundle';\nimport { StaticAttributes } from './interfaces/StaticAttributes';\nimport { BucketHistogram } from '../metrics/BucketHistogram';\nimport { UpCounter } from '../metrics/UpCounter';\nimport { ValueRecorder } from '../metrics/ValueRecorder';\nimport { version as schemaVersion } from 'o11y_schema/version';\nimport { MetricTag } from '../metrics/MetricTag';\n\nexport const coreEnvelopeKey = 'o11y';\nexport class CoreEnvelopeBuilder {\n private _envelope: CoreEnvelope;\n\n constructor() {\n this._envelope = {\n diagnostics: {\n key: coreEnvelopeKey,\n generatedTimestamp: undefined,\n bundleCount: 0,\n bucketHistogramCount: 0,\n upCounterCount: 0,\n valueRecorderCount: 0,\n schemaVersion\n },\n bundles: [] as MessageBundle[],\n metrics: {\n bucketHistograms: [] as BucketHistogram[],\n upCounters: [] as UpCounter[],\n valueRecorders: [] as ValueRecorder[]\n },\n staticAttributes: {}\n };\n }\n\n withStaticAttributes(staticAttributes: StaticAttributes): CoreEnvelopeBuilder {\n this._envelope.staticAttributes = staticAttributes;\n return this;\n }\n\n withLogs(schemaName: string, logs: LogMessage[]): CoreEnvelopeBuilder {\n let msgBundle: MessageBundle = this._envelope.bundles.find(\n (bundle) => bundle.schemaName === schemaName\n );\n\n if (msgBundle) {\n for (const log of logs) {\n msgBundle.messages.push(log);\n }\n } else {\n msgBundle = {\n schemaName: schemaName,\n messages: logs\n };\n this._envelope.bundles.push(msgBundle);\n }\n this._envelope.diagnostics.bundleCount = this._envelope.bundles.length;\n return this;\n }\n\n private static _getMetricTags<T>(metric: Metric<T>): MetricTag[] {\n const tags: MetricsTags = metric.getTags();\n if (tags) {\n return Object.entries(tags).map((entry) => {\n const mt: MetricTag = {\n name: entry[0],\n value: entry[1].toString()\n };\n return mt;\n });\n }\n return undefined;\n }\n\n static getUpCounters(metrics: Metric<number>[], reset = true): UpCounter[] {\n return metrics.map((metric) => {\n const data: UpCounter = {\n name: metric.getName(),\n createdTimestamp: metric.getCreatedOn(),\n lastUpdatedTimestamp: metric.getLastUpdatedOn(),\n value: metric.getData(),\n ownerName: metric.getOwnerName(),\n ownerAppName: metric.getOwnerAppName(),\n tags: this._getMetricTags(metric)\n };\n if (reset) {\n metric.reset();\n }\n return data;\n });\n }\n\n static getValueRecorders(metrics: Metric<number[]>[], reset = true): ValueRecorder[] {\n return metrics.map((metric) => {\n const data: ValueRecorder = {\n name: metric.getName(),\n createdTimestamp: metric.getCreatedOn(),\n lastUpdatedTimestamp: metric.getLastUpdatedOn(),\n values: metric.getData(),\n ownerName: metric.getOwnerName(),\n ownerAppName: metric.getOwnerAppName(),\n tags: this._getMetricTags(metric)\n };\n if (reset) {\n metric.reset();\n }\n return data;\n });\n }\n\n static getBucketHistograms(metrics: BucketMetric<number[]>[], reset = true): BucketHistogram[] {\n return metrics.map((metric) => {\n const data: BucketHistogram = {\n name: metric.getName(),\n createdTimestamp: metric.getCreatedOn(),\n lastUpdatedTimestamp: metric.getLastUpdatedOn(),\n values: metric.getData(),\n buckets: metric.getBuckets(),\n ownerName: metric.getOwnerName(),\n ownerAppName: metric.getOwnerAppName(),\n tags: this._getMetricTags(metric)\n };\n if (reset) {\n metric.reset();\n }\n return data;\n });\n }\n\n withUpCounters(upCounters: UpCounter[]): CoreEnvelopeBuilder {\n for (const upCounter of upCounters) {\n this._envelope.metrics.upCounters.push(upCounter);\n }\n this._envelope.diagnostics.upCounterCount = this._envelope.metrics.upCounters.length;\n return this;\n }\n\n withValueRecorders(valueRecorders: ValueRecorder[]): CoreEnvelopeBuilder {\n for (const valueRecorder of valueRecorders) {\n this._envelope.metrics.valueRecorders.push(valueRecorder);\n }\n this._envelope.diagnostics.valueRecorderCount =\n this._envelope.metrics.valueRecorders.length;\n return this;\n }\n\n withBucketHistograms(bucketHistograms: BucketHistogram[]): CoreEnvelopeBuilder {\n for (const bucketHistogram of bucketHistograms) {\n this._envelope.metrics.bucketHistograms.push(bucketHistogram);\n }\n this._envelope.diagnostics.bucketHistogramCount =\n this._envelope.metrics.bucketHistograms.length;\n return this;\n }\n\n build(): CoreEnvelope {\n this._envelope.diagnostics.generatedTimestamp = utility.time().tsNow;\n return this._envelope;\n }\n}\n","import { Root, Type } from 'protobufjs';\nimport { coreEnvelopeSchema } from 'o11y_schema/sf_instrumentation';\n\nimport {\n Environment,\n LogCollector,\n LogMeta,\n MetricsCollector,\n MetricsExtractorMethods,\n Schema\n} from '../../interfaces';\nimport { LazyMapToList, SchematizedData, schemaUtil, utility } from 'o11y/shared';\n\nimport { protobufUtil } from '../protobuf-util';\nimport { UploadMode } from './UploadMode';\nimport { CoreCollectorOptions } from './interfaces/CoreCollectorOptions';\nimport { CoreEnvelope } from './interfaces/CoreEnvelope';\nimport { CoreEnvelopeBuilder } from './CoreEnvelopeBuilder';\nimport { LogMessage } from './interfaces/LogMessage';\nimport { StaticAttributes } from './interfaces/StaticAttributes';\nimport { CoreEnvelopeContents } from './interfaces/CoreEnvelopeContents';\nimport { UploadResult } from './interfaces/UploadResult';\n\nconst defaultMaxUniqueSchemas = 10000;\nconst defaultMaxDelayBeforeUpload = 10000;\nconst defaultMessagesLimit = 10;\nconst defaultMetricsLimit = 10;\nconst defaultFormDataKey = 'telemetry';\nconst defaultUploadMode = UploadMode.fetchBinary;\n\nexport type UploadOptionsCallback = () => RequestInit;\n\nexport class CoreCollector implements LogCollector, MetricsCollector {\n private readonly _messageBuffers: LazyMapToList<Schema, LogMessage>;\n private readonly _coreEnvelopeType: Type;\n private _intervalHandle: NodeJS.Timeout;\n private _metricsExtractors: MetricsExtractorMethods;\n private readonly _staticAttributes: StaticAttributes;\n private _immediateUpload: boolean;\n private readonly _messagesLimit: number = defaultMessagesLimit;\n /*\n Known limitation:\n Unlike _messagesLimit, _metricsLimit is not a strict limit in all cases, as the CoreCollector\n doesn't get notified every time a new metric is added. Instead, it takes metrics into account\n when a message is logged or the upload timer is elapsed. If the _metricsLimit is exceeded \n with no messages logged and upload time not yet elapsed, upload will not occur.\n */\n private readonly _metricsLimit: number = defaultMetricsLimit;\n private readonly _formDataKey: string = defaultFormDataKey;\n private readonly _uploadFailedListener: (ur: UploadResult) => unknown;\n private _uploadInterval: number = defaultMaxDelayBeforeUpload;\n private _uploadEndpoint: string;\n private _uploadMode: UploadMode;\n private readonly _emptySize: number;\n private _messageSize = 0;\n private _uploadOptionsCallback: UploadOptionsCallback;\n\n constructor(\n uploadEndpoint?: string,\n uploadMode?: UploadMode,\n environment?: Environment,\n options?: CoreCollectorOptions\n ) {\n this.uploadEndpoint = uploadEndpoint;\n this.uploadMode = uploadMode == undefined ? defaultUploadMode : uploadMode;\n\n const root = Root.fromJSON(coreEnvelopeSchema.pbjsSchema);\n this._coreEnvelopeType = root.lookupType('CoreEnvelope');\n\n if (environment) {\n this._staticAttributes = {\n appName: environment.appName,\n appVersion: environment.appVersion,\n appExperience: environment.appExperience,\n deviceId: environment.deviceId,\n deviceModel: environment.deviceModel,\n sdkVersion: environment.sdkVersion\n };\n }\n\n let maxUniqueSchemas = defaultMaxUniqueSchemas;\n if (options) {\n const mus: number = options.maxUniqueSchemas;\n if (mus !== undefined) {\n if (typeof mus !== 'number' || !(mus > 0)) {\n throw new Error('options.maxUniqueSchemas, if defined, must be > 0');\n }\n maxUniqueSchemas = mus;\n }\n\n const msglim: number = options.messagesLimit;\n if (msglim !== undefined) {\n if (typeof msglim !== 'number' || !(msglim > 0)) {\n throw new Error('options.messagesLimit, if defined, must be > 0');\n }\n this._messagesLimit = msglim;\n }\n\n const metlim: number = options.metricsLimit;\n if (metlim !== undefined) {\n if (typeof metlim !== 'number' || !(metlim > 0)) {\n throw new Error('options.metricsLimit, if defined, must be > 0');\n }\n this._metricsLimit = metlim;\n }\n\n if (\n utility.requireArgumentIfDefined(\n options.formDataKeyName,\n 'options.formDataKeyName',\n 'string'\n )\n ) {\n this._formDataKey = options.formDataKeyName;\n }\n\n if (\n utility.requireArgumentIfDefined(\n options.uploadFailedListener,\n 'options.uploadFailedListener',\n 'function'\n )\n ) {\n this._uploadFailedListener = options.uploadFailedListener;\n }\n }\n this._messageBuffers = new LazyMapToList<Schema, LogMessage>(maxUniqueSchemas);\n\n this._emptySize = this.getByteSize(1);\n this._restartTimer();\n }\n\n get uploadInterval(): number {\n return this._uploadInterval;\n }\n set uploadInterval(uploadInterval: number) {\n if (uploadInterval === undefined) {\n uploadInterval = defaultMaxDelayBeforeUpload;\n }\n if (typeof uploadInterval !== 'number' || !(uploadInterval > 0)) {\n throw new Error('uploadInterval, if defined, must be > 0');\n }\n if (uploadInterval !== this._uploadInterval) {\n this._uploadInterval = uploadInterval;\n // Now that the interval has changed, restart the timer\n this._restartTimer();\n }\n }\n\n get uploadEndpoint(): string {\n return this._uploadEndpoint;\n }\n set uploadEndpoint(uploadEndpoint: string) {\n utility.requireArgumentIfDefined(uploadEndpoint, 'uploadEndpoint', 'string');\n this._uploadEndpoint = uploadEndpoint;\n }\n\n get uploadOptionsCallback(): UploadOptionsCallback {\n return this._uploadOptionsCallback;\n }\n set uploadOptionsCallback(uploadOptionsCallback: UploadOptionsCallback) {\n utility.requireArgumentIfDefined(\n uploadOptionsCallback,\n 'uploadOptionsCallback',\n 'function'\n );\n\n this._uploadOptionsCallback = uploadOptionsCallback;\n }\n\n get uploadMode(): UploadMode {\n return this._uploadMode;\n }\n set uploadMode(uploadMode: UploadMode) {\n utility.requireArgumentIfDefined(uploadMode, 'uploadMode', 'number');\n if (uploadMode === undefined) {\n uploadMode = defaultUploadMode;\n }\n if (!(uploadMode in UploadMode)) {\n throw new Error(`Unsupported upload mode: ${uploadMode}`);\n }\n this._uploadMode = uploadMode;\n }\n\n // Note: If making changes to this method, please locally test using SizeEstimation.test.js\n getByteSize(accuracy?: number): number {\n // This method provides an estimate.\n // Accuracy is specified as 1 = most accurate\n return accuracy >= 1\n ? this._buildProtoEncodedCoreEnvelope(false).byteLength\n : accuracy >= 0.5\n ? this._emptySize + this._messageSize + this.metricsCount * 8\n : this._emptySize + this._messageSize;\n }\n\n private _stopTimer(): void {\n if (this._intervalHandle !== undefined) {\n clearInterval(this._intervalHandle);\n this._intervalHandle = undefined;\n }\n }\n\n private _restartTimer(): void {\n this._stopTimer();\n this._intervalHandle = setInterval(() => {\n if (this.hasData) {\n this._upload();\n }\n }, this._uploadInterval);\n }\n\n // This method is implementing the LogCollector interface, but needs to return (not swallow)\n // the async result in order for direct call to it from test to handle failure cases properly.\n async collect(schema: Schema, data: SchematizedData, logMeta: LogMeta): Promise<UploadResult> {\n if (schemaUtil.isInternal(schema) && data.userPayload) {\n data.userPayload = protobufUtil.encodePayload(data.userPayload);\n }\n const msg: LogMessage = protobufUtil.getLogMessage(schema, data, logMeta);\n\n if (!this._messageBuffers.push(schema, msg)) {\n throw new Error(`Buffer is full. Refusing schemaId ${schemaUtil.getSchemaId(schema)}`);\n }\n // Get an estimate\n this._messageSize += utility.estimateObjectSize(msg);\n if (this._shouldUpload()) {\n return this._upload();\n }\n return undefined;\n }\n\n private _shouldUpload(): boolean {\n return (\n (this._immediateUpload && this.hasData) ||\n this.messagesCount >= this._messagesLimit ||\n this.metricsCount >= this._metricsLimit\n );\n }\n\n private async _upload(userInitiated?: boolean): Promise<UploadResult> {\n this._restartTimer();\n if (!this._uploadEndpoint || this._uploadMode === UploadMode.noUpload) {\n return undefined;\n }\n\n const contents: CoreEnvelopeContents = this._getContentsOfCoreEnvelope(true);\n return this._uploadContents(contents, userInitiated);\n }\n\n private async _uploadContents(\n contents: CoreEnvelopeContents,\n userInitiated: boolean\n ): Promise<UploadResult> {\n const coreEnvelope: Uint8Array = this._buildProtoEncodedCoreEnvelopeFrom(contents);\n\n let requestInit: RequestInit;\n switch (this._uploadMode) {\n case UploadMode.fetchBinary:\n requestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/octet-stream'\n },\n body: coreEnvelope\n };\n break;\n case UploadMode.fetchFile:\n const formData = new FormData();\n formData.append(this._formDataKey, new Blob([coreEnvelope]));\n // Per [this article](https://muffinman.io/uploading-files-using-fetch-multipart-form-data/)\n // make sure not to set the Content-Type header.\n // The browser will set it for you, including the boundary parameter.\n requestInit = {\n method: 'POST',\n body: formData\n };\n break;\n }\n\n const ur: UploadResult = {\n envelopeContents: contents\n };\n try {\n if (this._uploadOptionsCallback) {\n const options: RequestInit = this._uploadOptionsCallback() || {};\n if (options) {\n if (options.headers && requestInit.headers) {\n // According to lim.dom.d.ts:\n // type HeadersInit = string[][] | Record<string, string> | Headers;\n if (options.headers instanceof Headers) {\n for (const key in requestInit.headers) {\n if (\n Object.prototype.hasOwnProperty.call(requestInit.headers, key)\n ) {\n options.headers.set(\n key,\n (requestInit.headers as Record<string, string>)[key]\n );\n }\n }\n } else if (Array.isArray(options.headers)) {\n // This doesn't seem valid according to https://developer.mozilla.org/en-US/docs/Web/API/fetch\n throw new Error('Headers as array is not supported.');\n } else {\n Object.assign(options.headers, requestInit.headers);\n }\n }\n options.method = requestInit.method;\n options.body = requestInit.body;\n requestInit = options;\n }\n }\n\n ur.response = await fetch(this._uploadEndpoint, requestInit);\n // fetch only throws on network errors, not HTTP errors, so handle that here\n if (!ur.response.ok) {\n throw new Error('HTTP Not OK');\n }\n return ur;\n } catch (err) {\n ur.error = err;\n if (!userInitiated && this._uploadFailedListener) {\n try {\n this._uploadFailedListener(ur);\n } catch {}\n }\n throw ur;\n }\n }\n\n private _checkUploadState(): void {\n if (this._uploadEndpoint === undefined) {\n throw new Error('Upload endpoint is unset');\n }\n if (this._uploadMode === UploadMode.noUpload) {\n throw new Error('Upload mode is unset');\n }\n }\n\n // User initiated method\n public async upload(contents?: CoreEnvelopeContents): Promise<UploadResult> {\n this._checkUploadState();\n if (utility.requireArgumentIfDefined(contents, 'contents', 'object')) {\n return this._uploadContents(contents, true);\n }\n\n return this.hasData ? this._upload(true) : undefined;\n }\n\n get hasData(): boolean {\n return this.messagesCount > 0 || this.metricsCount > 0;\n }\n\n get messagesCount(): number {\n return this._messageBuffers.totalItemCount;\n }\n\n get metricsCount(): number {\n let count = 0;\n\n if (this._metricsExtractors) {\n let metrics: unknown[] = this._metricsExtractors.getAllUpCounters();\n count += (metrics && metrics.length) || 0;\n metrics = this._metricsExtractors.getAllValueRecorders();\n count += (metrics && metrics.length) || 0;\n metrics = this._metricsExtractors.getAllBucketHistograms();\n count += (metrics && metrics.length) || 0;\n }\n\n return count;\n }\n\n getProtoEncodedCoreEnvelope(): Uint8Array {\n return this._buildProtoEncodedCoreEnvelope(true);\n }\n\n getContentsOfCoreEnvelope(): CoreEnvelopeContents {\n return this._getContentsOfCoreEnvelope(true);\n }\n\n private _getContentsOfCoreEnvelope(extract: boolean): CoreEnvelopeContents {\n // 1. extract=true is for most use cases.\n // 2. extract=false is for peeking into the contents without affecting them\n // (i.e. messages are kept in the buffers and metrics are not reset.)\n // Message arrays are references to the originals and should be handled carefully.\n\n const contents: CoreEnvelopeContents = {\n staticAttributes: this._staticAttributes,\n messages: this._messageBuffers.getAllMessages(extract)\n };\n\n if (this._metricsExtractors) {\n contents.upCounters = CoreEnvelopeBuilder.getUpCounters(\n this._metricsExtractors.getAllUpCounters(),\n extract\n );\n contents.valueRecorders = CoreEnvelopeBuilder.getValueRecorders(\n this._metricsExtractors.getAllValueRecorders(),\n extract\n );\n contents.bucketHistograms = CoreEnvelopeBuilder.getBucketHistograms(\n this._metricsExtractors.getAllBucketHistograms(),\n extract\n );\n }\n\n if (extract) {\n this._messageSize = 0;\n }\n return contents;\n }\n\n private _buildProtoEncodedCoreEnvelope(extract: boolean): Uint8Array {\n const contents: CoreEnvelopeContents = this._getContentsOfCoreEnvelope(extract);\n return this._buildProtoEncodedCoreEnvelopeFrom(contents);\n }\n\n private _buildProtoEncodedCoreEnvelopeFrom(contents?: CoreEnvelopeContents): Uint8Array {\n const builder = new CoreEnvelopeBuilder();\n\n if (contents.staticAttributes) {\n builder.withStaticAttributes(contents.staticAttributes);\n }\n if (contents.messages) {\n contents.messages.forEach((logs: LogMessage[], schema: Schema) => {\n builder.withLogs(schemaUtil.getSchemaId(schema), logs);\n });\n }\n if (contents.upCounters) {\n builder.withUpCounters(contents.upCounters);\n }\n if (contents.valueRecorders) {\n builder.withValueRecorders(contents.valueRecorders);\n }\n if (contents.bucketHistograms) {\n builder.withBucketHistograms(contents.bucketHistograms);\n }\n\n return this._encodeCoreEnvelope(builder.build());\n }\n\n private _encodeCoreEnvelope(coreEnvelope: CoreEnvelope): Uint8Array {\n const errorMessage = this._coreEnvelopeType.verify(coreEnvelope);\n if (errorMessage) {\n throw new Error(`Invalid CoreEnvelope: ${errorMessage}`);\n }\n\n const encodedCoreEnvelope = this._coreEnvelopeType.encode(coreEnvelope).finish();\n return encodedCoreEnvelope;\n }\n\n receiveMetricsExtractors(metricsExtractors: MetricsExtractorMethods): void {\n this._metricsExtractors = metricsExtractors;\n }\n}\n","import {\n BucketMetric,\n LogCollector,\n LogMeta,\n Metric,\n MetricsCollector,\n MetricsExtractorMethods,\n Schema\n} from '../../interfaces';\nimport { SchematizedData, MetricsTags, schemaUtil, utility } from 'o11y/shared';\nimport { protobufUtil } from '../protobuf-util';\nimport { LogMessage } from '../core-collector/interfaces/LogMessage';\nimport { EncodedSchematizedPayload } from '../EncodedSchematizedPayload';\nimport { MetricTag } from '../metrics/MetricTag';\nimport { UpCounter } from '../metrics/UpCounter';\nimport { ValueRecorder } from '../metrics/ValueRecorder';\nimport { BucketHistogram } from '../metrics/BucketHistogram';\nimport { Metrics } from '../metrics/Metrics';\n\nconst metricsCollectionMilliseconds = 30000;\n\n// The observability plugin expects encoded payloads, so can't use LogMeta as-is.\ninterface LogMetaObservability {\n timestamp: number;\n rootId: string;\n sequence: number;\n loggerName: string;\n pagePayload: EncodedSchematizedPayload;\n loggerAppName: string;\n connectionType: string;\n appPayload: EncodedSchematizedPayload;\n}\n\n// The following interface is expected to be fulfilled by the\n// observability plugin in Lightning SDK.\ndeclare type NimbusObservabilityPlugin = {\n // Called to send a collected message to native for handling\n log: (schema: string, encodedMessage: Uint8Array, logMeta: LogMetaObservability) => void;\n\n // Called to send metrics to native for handling\n logMetrics: (metrics: Metrics) => void;\n\n // Called to listen for root activity changes in native.\n //\n // The startListener is called with the id of the root activity when an activity is started\n // The stopListener is called when a root activity is stopped\n addRootActivityListeners: (\n startListener: (activityInfo: { id: string }) => void,\n stopListener: () => void\n ) => void;\n\n // Called to inform native that the web view has detected an idle state.\n idleDetected: (timestamp: number) => void;\n};\n\n// The `HybridCollector` uses nimbus to send log data immediately across\n// to be handled by the native observability library.\nexport class HybridCollector implements LogCollector, MetricsCollector {\n private readonly _observability: NimbusObservabilityPlugin;\n private _metricsExtractors: MetricsExtractorMethods;\n\n constructor() {\n if (typeof __nimbus === 'undefined') {\n throw new Error('Nimbus is unavailable');\n }\n if (!__nimbus.plugins || !__nimbus.plugins.observability) {\n throw new Error('Observability plugin not found in Nimbus plugins');\n }\n this._observability = __nimbus.plugins.observability as NimbusObservabilityPlugin;\n setInterval(() => {\n this._collectMetrics();\n }, metricsCollectionMilliseconds);\n }\n\n collect(schema: Schema, data: SchematizedData, logMeta: LogMeta): void {\n if (schemaUtil.isInternal(schema) && data.userPayload) {\n data.userPayload = protobufUtil.encodePayload(data.userPayload);\n }\n const logMessage: LogMessage = protobufUtil.getLogMessage(schema, data, logMeta);\n const logMetaObs: LogMetaObservability = {\n timestamp: logMeta.timestamp,\n rootId: logMeta.rootId,\n sequence: logMeta.sequence,\n loggerName: logMeta.loggerName,\n pagePayload: logMessage.pagePayload,\n loggerAppName: logMeta.loggerAppName,\n connectionType: logMeta.connectionType,\n appPayload: logMessage.appPayload\n };\n this._observability.log(schemaUtil.getSchemaId(schema), logMessage.data, logMetaObs);\n }\n\n receiveMetricsExtractors(metricsExtractors: MetricsExtractorMethods): void {\n this._metricsExtractors = metricsExtractors;\n }\n\n // An app can call this method to listen for root activities that start and stop\n // on the native side, in order to associate web activities with the same root id.\n addRootActivityListeners(\n activityStarted: (info: { id: string }) => void,\n activityEnded: () => void\n ): void {\n utility.requireArgument(activityStarted, 'activityStarted', 'function');\n utility.requireArgument(activityEnded, 'activityEnded', 'function');\n\n this._observability.addRootActivityListeners(activityStarted, activityEnded);\n }\n\n // An app should call this method when it detects idle in the web view in order\n // to inform the native app of the idle state.\n notifyIdleDetected(timestamp: number): void {\n this._observability.idleDetected(timestamp);\n }\n\n private _collectMetrics(): void {\n if (this._metricsExtractors) {\n const upCounters: Metric<number>[] = this._metricsExtractors.getAllUpCounters();\n const valueRecorders: Metric<number[]>[] =\n this._metricsExtractors.getAllValueRecorders();\n const bucketHistograms: BucketMetric<number[]>[] =\n this._metricsExtractors.getAllBucketHistograms();\n const recorders: ValueRecorder[] = [];\n const counters: UpCounter[] = [];\n const histograms: BucketHistogram[] = [];\n\n for (const valueRecorder of valueRecorders) {\n const vr: ValueRecorder = {\n name: valueRecorder.getName(),\n createdTimestamp: valueRecorder.getCreatedOn(),\n lastUpdatedTimestamp: valueRecorder.getLastUpdatedOn(),\n values: valueRecorder.getData(),\n ownerName: valueRecorder.getOwnerName(),\n ownerAppName: valueRecorder.getOwnerAppName(),\n tags: this._getMetricTags(valueRecorder)\n };\n recorders.push(vr);\n valueRecorder.reset();\n }\n\n for (const upCounter of upCounters) {\n const uc: UpCounter = {\n name: upCounter.getName(),\n createdTimestamp: upCounter.getCreatedOn(),\n lastUpdatedTimestamp: upCounter.getLastUpdatedOn(),\n value: upCounter.getData(),\n ownerName: upCounter.getOwnerName(),\n ownerAppName: upCounter.getOwnerAppName(),\n tags: this._getMetricTags(upCounter)\n };\n counters.push(uc);\n upCounter.reset();\n }\n\n for (const bucketHistogram of bucketHistograms) {\n const bh: BucketHistogram = {\n name: bucketHistogram.getName(),\n createdTimestamp: bucketHistogram.getCreatedOn(),\n lastUpdatedTimestamp: bucketHistogram.getLastUpdatedOn(),\n values: bucketHistogram.getData(),\n buckets: bucketHistogram.getBuckets(),\n ownerName: bucketHistogram.getOwnerName(),\n ownerAppName: bucketHistogram.getOwnerAppName(),\n tags: this._getMetricTags(bucketHistogram)\n };\n histograms.push(bh);\n bucketHistogram.reset();\n }\n\n if (recorders.length > 0 || counters.length > 0) {\n const metrics: Metrics = {\n upCounters: counters,\n valueRecorders: recorders,\n bucketHistograms: histograms\n };\n this._observability.logMetrics(metrics);\n }\n }\n }\n\n private _getMetricTags<T>(metric: Metric<T>): MetricTag[] {\n const metricsTags: MetricsTags = metric.getTags();\n\n if (metricsTags) {\n return Object.entries(metricsTags).map((entry) => {\n const mt: MetricTag = {\n name: entry[0],\n value: entry[1].toString()\n };\n return mt;\n });\n }\n return [];\n }\n}\n"],"names":["schemaVersion"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "o11y",
3
- "version": "240.8.0",
3
+ "version": "240.9.0",
4
4
  "description": "O11y Client-Side Instrumentation & Observability Library",
5
5
  "main": "index.js",
6
6
  "exports": {
@@ -37,7 +37,7 @@
37
37
  "author": "Instrumentation Team",
38
38
  "license": "BSD-3-Clause",
39
39
  "dependencies": {
40
- "o11y_schema": "240.11.0",
40
+ "o11y_schema": "240.15.1",
41
41
  "protobufjs": "6.11.3",
42
42
  "web-vitals": "2.1.4"
43
43
  },