Skip to content

Commit

Permalink
feat: improve CLI UI + add metric reader + more configs (#139)
Browse files Browse the repository at this point in the history
* feat: improve cli ui

* feat: handle shutdown

* feat: config logger

* feat: get logger exporter url

* feat: enable console + exception + sentry int by default for init

* docs: add changeset

* feat: add HDX_STARTUP_LOGS flag

* style: pretty print configs

* feat: open dashboard automatically on local

* feat: disable browser thing for now

* feat: enable betaMode by default

* feat: add hyperdx metric meter + flags to disable logs/tracing/metrics

* feat: env to disable logs/metrics/tracing
+ inject metric exporter headers

* style: set the otlp header env

* chore: disable betaMode for now
  • Loading branch information
wrn14897 authored Jun 13, 2024
1 parent 52dca89 commit 24a581e
Show file tree
Hide file tree
Showing 10 changed files with 599 additions and 324 deletions.
5 changes: 5 additions & 0 deletions .changeset/curvy-teachers-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hyperdx/node-opentelemetry': patch
---

feat: config logger
5 changes: 5 additions & 0 deletions .changeset/sweet-pets-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hyperdx/node-opentelemetry': patch
---

feat: improve CLI UI
5 changes: 1 addition & 4 deletions packages/node-opentelemetry/examples/dummy.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@ const {
const HyperDX = require('../build/src');

HyperDX.init({
betaMode: true,
consoleCapture: true,
experimentalExceptionCapture: true,
sentryIntegrationEnabled: true,
apiKey: 'blabla',
});

// setTimeout(() => {
Expand Down
4 changes: 4 additions & 0 deletions packages/node-opentelemetry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,20 @@
"@opentelemetry/exporter-trace-otlp-proto": "^0.51.1",
"@opentelemetry/instrumentation": "^0.51.1",
"@opentelemetry/instrumentation-http": "^0.51.1",
"@opentelemetry/instrumentation-runtime-node": "^0.5.0",
"@opentelemetry/resources": "^1.24.1",
"@opentelemetry/sdk-logs": "^0.51.1",
"@opentelemetry/sdk-metrics": "^1.24.1",
"@opentelemetry/sdk-node": "^0.51.1",
"@opentelemetry/sdk-trace-base": "^1.24.1",
"@opentelemetry/semantic-conventions": "^1.24.1",
"cli-spinners": "^2.9.2",
"json-stringify-safe": "^5.0.1",
"lodash.isobject": "^3.0.2",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"open": "^8.4.2",
"ora": "^5.4.1",
"pino-abstract-transport": "^1.2.0",
"semver": "^7.6.2",
"shimmer": "^1.2.1",
Expand Down
27 changes: 19 additions & 8 deletions packages/node-opentelemetry/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,35 @@ export const DEFAULT_EXPORTER_BATCH_SIZE =
export const DEFAULT_EXPORTER_TIMEOUT_MS =
otelEnv.OTEL_BLRP_EXPORT_TIMEOUT ?? 30000;
export const DEFAULT_MAX_QUEUE_SIZE = otelEnv.OTEL_BLRP_MAX_QUEUE_SIZE ?? 2048;
export const DEFAULT_OTEL_TRACES_EXPORTER = otelEnv.OTEL_TRACES_EXPORTER;
export const DEFAULT_OTEL_TRACES_EXPORTER_URL =
otelEnv.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ??
(otelEnv.OTEL_EXPORTER_OTLP_ENDPOINT
? `${otelEnv.OTEL_EXPORTER_OTLP_ENDPOINT}/v1/traces`
: 'https://in-otel.hyperdx.io/v1/traces');
export const DEFAULT_OTEL_TRACES_SAMPLER =
otelEnv.OTEL_TRACES_SAMPLER ?? 'parentbased_always_on';
export const DEFAULT_OTEL_TRACES_SAMPLER_ARG =
otelEnv.OTEL_TRACES_SAMPLER_ARG ?? '1';
export const DEFAULT_OTEL_EXPORTER_OTLP_TRACES_TIMEOUT =
otelEnv.OTEL_EXPORTER_OTLP_TRACES_TIMEOUT ?? 60000;
export const DEFAULT_SEND_INTERVAL_MS =
otelEnv.OTEL_BLRP_SCHEDULE_DELAY ?? 2000;
export const DEFAULT_OTEL_LOGS_EXPORTER = otelEnv.OTEL_LOGS_EXPORTER;
export const DEFAULT_OTEL_LOGS_EXPORTER_URL =
otelEnv.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT ??
(otelEnv.OTEL_EXPORTER_OTLP_ENDPOINT
? `${otelEnv.OTEL_EXPORTER_OTLP_ENDPOINT}/v1/logs`
: 'https://in-otel.hyperdx.io/v1/logs');
export const DEFAULT_SEND_INTERVAL_MS =
otelEnv.OTEL_BLRP_SCHEDULE_DELAY ?? 2000;
export const DEFAULT_OTEL_METRICS_EXPORTER = (otelEnv as any)
.OTEL_METRICS_EXPORTER; // not exist yet
export const DEFAULT_OTEL_METRICS_EXPORTER_URL =
otelEnv.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT ??
(otelEnv.OTEL_EXPORTER_OTLP_ENDPOINT
? `${otelEnv.OTEL_EXPORTER_OTLP_ENDPOINT}/v1/metrics`
: 'https://in-otel.hyperdx.io/v1/metrics');
export const DEFAULT_SERVICE_NAME =
otelEnv.OTEL_SERVICE_NAME ?? defaultServiceName();
export const DEFAULT_OTEL_TRACES_SAMPLER =
otelEnv.OTEL_TRACES_SAMPLER ?? 'parentbased_always_on';
export const DEFAULT_OTEL_TRACES_SAMPLER_ARG =
otelEnv.OTEL_TRACES_SAMPLER_ARG ?? '1';
export const DEFAULT_OTEL_EXPORTER_OTLP_TRACES_TIMEOUT =
otelEnv.OTEL_EXPORTER_OTLP_TRACES_TIMEOUT ?? 60000;
export const DEFAULT_OTEL_LOG_LEVEL = otelEnvWithDefaults.OTEL_LOG_LEVEL;

// HyperDX SDK specific configuration
Expand All @@ -53,3 +62,5 @@ export const DEFAULT_HDX_NODE_SENTRY_INTEGRATION_ENABLED =
stringToBoolean(env.HDX_NODE_SENTRY_INTEGRATION_ENABLED) ?? false;
export const DEFAULT_HDX_NODE_ENABLE_INTERNAL_PROFILING =
stringToBoolean(env.HDX_NODE_ENABLE_INTERNAL_PROFILING) ?? false;
export const DEFAULT_HDX_STARTUP_LOGS =
stringToBoolean(env.HDX_STARTUP_LOGS) ?? true;
19 changes: 9 additions & 10 deletions packages/node-opentelemetry/src/metrics.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import {
MeterProvider,
PeriodicExportingMetricReader,
} from '@opentelemetry/sdk-metrics';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto';
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';

export const metricReader = new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter(),
exportIntervalMillis: 1000,
});
import { DEFAULT_OTEL_METRICS_EXPORTER_URL } from './constants';

export const meterProvider = new MeterProvider({});
meterProvider.addMetricReader(metricReader);
export const getHyperDXMetricReader = () =>
new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter({
url: DEFAULT_OTEL_METRICS_EXPORTER_URL,
}),
exportIntervalMillis: 1000,
});
66 changes: 47 additions & 19 deletions packages/node-opentelemetry/src/otel-logger/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Attributes, diag } from '@opentelemetry/api';
import { getEnvWithoutDefaults } from '@opentelemetry/core';
import {
BatchLogRecordProcessor,
LoggerProvider,
NoopLogRecordProcessor,
} from '@opentelemetry/sdk-logs';
import { Logger as OtelLogger } from '@opentelemetry/api-logs';
import { Logger as OtelLogger, logs } from '@opentelemetry/api-logs';
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
import {
Resource,
Expand Down Expand Up @@ -40,9 +42,13 @@ export type LoggerOptions = {
};

export class Logger {
private readonly _url: string;

private readonly logger: OtelLogger;

private readonly processor: BatchLogRecordProcessor;
private readonly processor: BatchLogRecordProcessor | NoopLogRecordProcessor;

private readonly provider: LoggerProvider;

constructor({
baseUrl,
Expand All @@ -56,7 +62,7 @@ export class Logger {
timeout,
}: LoggerOptions) {
if (!service) {
console.warn(
diag.warn(
`${LOG_PREFIX} Service name not found. Use "${DEFAULT_SERVICE_NAME}"`,
);
}
Expand All @@ -65,7 +71,7 @@ export class Logger {
const maxExportBatchSize = bufferSize ?? DEFAULT_EXPORTER_BATCH_SIZE;
let maxQueueSize = queueSize ?? DEFAULT_MAX_QUEUE_SIZE;
if (maxExportBatchSize > maxQueueSize) {
console.error(
diag.error(
`${LOG_PREFIX} bufferSize must be smaller or equal to queueSize. Setting queueSize to ${maxExportBatchSize}`,
);
maxQueueSize = maxExportBatchSize;
Expand All @@ -77,23 +83,25 @@ export class Logger {
: [],
});

const _url = baseUrl ?? DEFAULT_OTEL_LOGS_EXPORTER_URL;
this._url = baseUrl ?? DEFAULT_OTEL_LOGS_EXPORTER_URL;

console.warn(`${LOG_PREFIX} Sending logs to ${_url}`);
diag.warn(`${LOG_PREFIX} Sending logs to ${this._url}`);

const exporter = new OTLPLogExporter({
url: _url,
url: this._url,
...(headers && { headers }),
});
this.processor = new BatchLogRecordProcessor(exporter, {
/** The maximum batch size of every export. It must be smaller or equal to
* maxQueueSize. The default value is 512. */
maxExportBatchSize,
scheduledDelayMillis: sendIntervalMs ?? DEFAULT_SEND_INTERVAL_MS,
exportTimeoutMillis: timeout ?? DEFAULT_EXPORTER_TIMEOUT_MS,
maxQueueSize,
});
const loggerProvider = new LoggerProvider({
this.processor = this.isDisabled()
? new NoopLogRecordProcessor()
: new BatchLogRecordProcessor(exporter, {
/** The maximum batch size of every export. It must be smaller or equal to
* maxQueueSize. The default value is 512. */
maxExportBatchSize,
scheduledDelayMillis: sendIntervalMs ?? DEFAULT_SEND_INTERVAL_MS,
exportTimeoutMillis: timeout ?? DEFAULT_EXPORTER_TIMEOUT_MS,
maxQueueSize,
});
this.provider = new LoggerProvider({
resource: detectedResource.merge(
new Resource({
// TODO: should use otel semantic conventions
Expand All @@ -103,10 +111,9 @@ export class Logger {
}),
),
});
loggerProvider.addLogRecordProcessor(this.processor);
this.provider.addLogRecordProcessor(this.processor);

this.logger = loggerProvider.getLogger('node-logger');
console.log(`${LOG_PREFIX} started!`);
this.logger = this.provider.getLogger('node-logger');
}

private parseTimestamp(meta: Attributes): Date {
Expand All @@ -118,6 +125,27 @@ export class Logger {
return new Date();
}

isDisabled() {
return getEnvWithoutDefaults().OTEL_LOGS_EXPORTER === 'none';
}

setGlobalLoggerProvider() {
diag.debug('Setting global logger provider...');
logs.setGlobalLoggerProvider(this.provider);
}

getExporterUrl() {
return this._url;
}

getProvider() {
return this.provider;
}

getProcessor() {
return this.processor;
}

shutdown() {
diag.debug('Shutting down HyperDX node logger...');
return this.processor.shutdown();
Expand Down
Loading

0 comments on commit 24a581e

Please sign in to comment.