From 016f93d150a58cbc215ada263024762adde5300e Mon Sep 17 00:00:00 2001 From: Matt Straathof Date: Tue, 28 May 2024 16:29:31 -0700 Subject: [PATCH] feat: add support for pointing lambda metrics to generic downstream otlp provider --- src/goodmetrics/metricsSetups.ts | 78 +++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/src/goodmetrics/metricsSetups.ts b/src/goodmetrics/metricsSetups.ts index ad79095..0d0e4c3 100644 --- a/src/goodmetrics/metricsSetups.ts +++ b/src/goodmetrics/metricsSetups.ts @@ -49,6 +49,41 @@ interface LightstepNativeLambdaOtlpProps { onSendUnary?: (metrics: Metrics[]) => void; } +interface RawNativeLambdaOtlpForLambdaProps { + /** + * programmatic access token for the otlp metric backend + */ + accessToken: string; + /** + * Name of the header to use for authentication. Ex. `api-token` + */ + authHeaderName: string; + /** + * Included resource dimensions on the OTLP resource. Ex. AWS_REGION, ACCOUNT_ID etc... + */ + resourceDimensions: Map; + /** + * Include resource dimensions on each metric instead of on the Resource. You'd use this for + * downstreams that either do not support or do something undesirable with Resource dimensions. + */ + sharedDimensions: Map; + /** + * example `ingest.lightstep.com` + */ + ingestUrl: string; + /** + * defaults to 443 + */ + ingestPort?: number; + logError: (message: string, error: unknown) => void; + /** + * Mostly for debugging purposes, logs after successfully sending metrics to the backend. + * Used to tell if the promise fully resolved + */ + doLogSuccess?: boolean; + onSendUnary?: (metrics: Metrics[]) => void; +} + interface ConfigureBatchedUnaryLightstepSinkProps { batchSize: number; batchMaxAgeSeconds: number; @@ -165,7 +200,7 @@ export class MetricsSetups { } /** - * Configures a unary metric factory which will send and record metrics upon lambda + * Configures a unary metric factory pointing to lightstep downstream, which will send and record metrics upon lambda * completion * @param props */ @@ -205,6 +240,47 @@ export class MetricsSetups { }); } + /** + * Configures a unary metric factory pointing to any arbitrary oltp metrics backend, which will send and record metrics upon lambda + * completion + * @param props + */ + static rawNativeOtlpButItSendsMetricsUponRecordingForLambda( + props: RawNativeLambdaOtlpForLambdaProps + ): MetricsFactory { + const headers = [ + new Header(props.authHeaderName, props.accessToken), + ]; + const client = OpenTelemetryClient.connect({ + sillyOtlpHostname: props.ingestUrl, + port: props.ingestPort ?? 443, + metricDimensions: props.sharedDimensions, + resourceDimensions: props.resourceDimensions, + interceptors: [ + new HeaderInterceptorProvider(headers).createHeadersInterceptor(), + ], + }); + const unarySink: MetricsSink = { + close(): void { + client.close(); + }, + async emit(metrics: _Metrics): Promise { + props?.onSendUnary && props.onSendUnary([metrics]); + try { + await client.sendMetricsBatch([metrics]); + props.doLogSuccess && console.log('metrics sent to backend'); + } catch (e) { + props.logError('error while sending blocking metrics', e); + } + }, + }; + + return new MetricsFactory({ + metricsSink: unarySink, + totalTimeType: TotaltimeType.DistributionMilliseconds, + }); + } + private static configureBatchedUnaryLightstepSink( props: ConfigureBatchedUnaryLightstepSinkProps ): SynchronizingBuffer {