You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I want to send logs from my frontend and bind them with traces. I've already setup traces with auto-instrumentation:
import { BatchSpanProcessor, WebTracerProvider } from "@opentelemetry/sdk-trace-web";
import { ZoneContextManager } from "@opentelemetry/context-zone";
import { registerInstrumentations } from "@opentelemetry/instrumentation";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
import { defaultResource, resourceFromAttributes } from "@opentelemetry/resources";
import { getWebAutoInstrumentations } from "@opentelemetry/auto-instrumentations-web";
export class OtelCollector {
static #instance: OtelCollector | null;
// eslint-disable-next-line @typescript-eslint/no-empty-function
private constructor() {}
public static initialize(appName: string, url: string): void {
if (OtelCollector.#instance) {
return;
}
OtelCollector.#instance = new OtelCollector();
const collectorOptions = {
url,
};
const resource = defaultResource().merge(
resourceFromAttributes({
[ATTR_SERVICE_NAME]: appName,
})
);
const exporter = new OTLPTraceExporter(collectorOptions);
const provider = new WebTracerProvider({
resource,
spanProcessors: [new BatchSpanProcessor(exporter)],
});
provider.register({
contextManager: new ZoneContextManager(),
});
registerInstrumentations({
instrumentations: [getWebAutoInstrumentations()],
});
}
}
Here I found a simple example how to setup logs. My implementation is
import { trace, context } from "@opentelemetry/api";
import { SeverityNumber, type Logger } from "@opentelemetry/api-logs";
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
import { defaultResource, resourceFromAttributes } from "@opentelemetry/resources";
import { LoggerProvider, SimpleLogRecordProcessor } from "@opentelemetry/sdk-logs";
import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
let otelLogger: Logger | undefined;
export function initializeLogging(): Logger {
if (otelLogger) {
return otelLogger;
}
// exporter options. see all options in OTLPExporterConfigBase
const collectorOptions = {
url: "myHardcodedLogUrl", // url is optional and can be omitted - default is http://localhost:4318/v1/logs
headers: {}, // an optional object containing custom headers to be sent with each request
concurrencyLimit: 1, // an optional limit on pending requests
};
const logExporter = new OTLPLogExporter(collectorOptions);
const resource = defaultResource().merge(
resourceFromAttributes({
[ATTR_SERVICE_NAME]: "MyAppName",
})
);
const loggerProvider = new LoggerProvider({
resource,
processors: [new SimpleLogRecordProcessor(logExporter)],
});
otelLogger = loggerProvider.getLogger("default", "1.0.0");
return otelLogger;
}
export enum LogTag {
ERROR = "Error",
WARNING = "Warning",
INFO = "Info",
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function logInfo(...messages: any[]): void {
log(LogTag.INFO, ...messages);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function logError(...messages: any[]): void {
log(LogTag.ERROR, ...messages);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function logWarning(...messages: any[]): void {
log(LogTag.WARNING, ...messages);
}
function log(tag: LogTag = LogTag.INFO, ...messages: any[]): void {
const logBase = `${getTimeStamp().trim()}|${tag}|`;
if (tag === LogTag.INFO) {
// eslint-disable-next-line no-console
console.log(logBase, ...messages);
emit(SeverityNumber.INFO, LogTag.INFO, logBase, ...messages);
}
if (tag === LogTag.WARNING) {
console.warn(logBase, ...messages);
emit(SeverityNumber.WARN, LogTag.WARNING, logBase, ...messages);
}
if (tag === LogTag.ERROR) {
console.error(logBase, ...messages);
emit(SeverityNumber.ERROR, LogTag.ERROR, logBase, ...messages);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function emit(severityNumber: SeverityNumber, severityText: string, ...messages: any[]): void {
// const otelLogger = logs.getLogger("default", "1.0.0");
if (otelLogger === undefined) {
return;
}
const span = trace.getSpan(context.active());
const traceId = span?.spanContext().traceId;
const spanId = span?.spanContext().spanId;
// Emit a log
otelLogger.emit({
severityNumber,
severityText,
body: messages.reduce((accumulator: string, message: unknown) => `${accumulator} ${String(message)}`, ""),
attributes: { "log.type": "custom", ...(traceId && { traceId }), ...(spanId && { spanId }) },
});
}
}
function getTimeStamp(): string {
// implementation
}
This is how I initialize the traces and loggs in main.ts file. I wanted to initialize liggs after tracs in order to be sure that auto-instriumentation was setup before logging.
I cannot get a traceId and the span in this line const span = trace.getSpan(context.active()); is always undefined.
The application sends http requests and I tried to add logs as close to requests as possible, but still I have logs without connection to the traces.
In the begining I also tried without const span = trace.getSpan(context.active()); and it didn't work.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
I want to send logs from my frontend and bind them with traces. I've already setup traces with auto-instrumentation:
Here I found a simple example how to setup logs. My implementation is
This is how I initialize the traces and loggs in main.ts file. I wanted to initialize liggs after tracs in order to be sure that auto-instriumentation was setup before logging.
I cannot get a traceId and the span in this line const span = trace.getSpan(context.active()); is always undefined.
The application sends http requests and I tried to add logs as close to requests as possible, but still I have logs without connection to the traces.
In the begining I also tried without const span = trace.getSpan(context.active()); and it didn't work.
Any idea, how to mke it working?
P.S. I use React with redux queries.
Beta Was this translation helpful? Give feedback.
All reactions