Get started
Logs monitoring
Exceptions and errors
Kubernetes
Migrating from Datadog
Migrating from NewRelic
Hosted
C++
.NET
Erlang/Elixir
Golang
Java
JavaScript
PHP
Python
Ruby
Rust
Swift
OpenTelemetry Logs for C++
Prerequisites
Make sure your exporter is configured before you start instrumenting code. Follow Getting started with OpenTelemetry C++ or set up OTLP Configuration first.
If you are not familiar with logs terminology, read the introduction to OpenTelemetry Logs first.
Overview
OpenTelemetry C++ provides a native Logs API for emitting structured log records. The Logs API integrates with the tracing system to automatically correlate logs with traces.
Configuration
cpp
#include <cstdlib>
#include "opentelemetry/exporters/otlp/otlp_http_log_record_exporter_factory.h"
#include "opentelemetry/exporters/otlp/otlp_http_log_record_exporter_options.h"
#include "opentelemetry/sdk/logs/logger_provider_factory.h"
#include "opentelemetry/sdk/logs/simple_log_record_processor_factory.h"
#include "opentelemetry/logs/provider.h"
namespace otlp = opentelemetry::exporter::otlp;
namespace logs_sdk = opentelemetry::sdk::logs;
namespace logs_api = opentelemetry::logs;
void InitLogger() {
otlp::OtlpHttpLogRecordExporterOptions opts;
opts.url = "https://api.uptrace.dev/v1/logs";
const char* dsn = std::getenv("UPTRACE_DSN");
opts.http_headers = {{"uptrace-dsn", dsn ? dsn : ""}};
auto exporter = otlp::OtlpHttpLogRecordExporterFactory::Create(opts);
auto processor = logs_sdk::SimpleLogRecordProcessorFactory::Create(
std::move(exporter));
std::shared_ptr<logs_api::LoggerProvider> provider =
logs_sdk::LoggerProviderFactory::Create(std::move(processor));
logs_api::Provider::SetLoggerProvider(provider);
}
Emitting logs
cpp
auto logger = logs_api::Provider::GetLoggerProvider()
->GetLogger("myservice", "1.0.0");
logger->EmitLogRecord(
logs_api::Severity::kInfo,
"Application started successfully"
);
Severity levels
cpp
logger->EmitLogRecord(logs_api::Severity::kTrace, "Trace message");
logger->EmitLogRecord(logs_api::Severity::kDebug, "Debug message");
logger->EmitLogRecord(logs_api::Severity::kInfo, "Info message");
logger->EmitLogRecord(logs_api::Severity::kWarn, "Warning message");
logger->EmitLogRecord(logs_api::Severity::kError, "Error message");
logger->EmitLogRecord(logs_api::Severity::kFatal, "Fatal message");
Log-trace correlation
When you emit a log within an active trace span, OpenTelemetry automatically includes:
- trace_id: Links log to the entire distributed trace
- span_id: Links log to the specific operation
cpp
#include "opentelemetry/trace/provider.h"
#include "opentelemetry/logs/provider.h"
namespace trace_api = opentelemetry::trace;
namespace logs_api = opentelemetry::logs;
void processRequest() {
auto tracer = trace_api::Provider::GetTracerProvider()->GetTracer("myservice");
auto logger = logs_api::Provider::GetLoggerProvider()->GetLogger("myservice");
auto span = tracer->StartSpan("process-request");
auto scope = tracer->WithActiveSpan(span);
// Logs are automatically correlated with the span
logger->EmitLogRecord(logs_api::Severity::kInfo, "Processing request");
span->End();
}
Complete example
cpp
#include <cstdlib>
#include "opentelemetry/exporters/otlp/otlp_http_log_record_exporter_factory.h"
#include "opentelemetry/exporters/otlp/otlp_http_log_record_exporter_options.h"
#include "opentelemetry/sdk/logs/logger_provider_factory.h"
#include "opentelemetry/sdk/logs/logger_provider.h"
#include "opentelemetry/sdk/logs/simple_log_record_processor_factory.h"
#include "opentelemetry/logs/provider.h"
namespace otlp = opentelemetry::exporter::otlp;
namespace logs_sdk = opentelemetry::sdk::logs;
namespace logs_api = opentelemetry::logs;
void InitLogger() {
otlp::OtlpHttpLogRecordExporterOptions opts;
opts.url = "https://api.uptrace.dev/v1/logs";
const char* dsn = std::getenv("UPTRACE_DSN");
opts.http_headers = {{"uptrace-dsn", dsn ? dsn : ""}};
auto exporter = otlp::OtlpHttpLogRecordExporterFactory::Create(opts);
auto processor = logs_sdk::SimpleLogRecordProcessorFactory::Create(
std::move(exporter));
std::shared_ptr<logs_api::LoggerProvider> provider =
logs_sdk::LoggerProviderFactory::Create(std::move(processor));
logs_api::Provider::SetLoggerProvider(provider);
}
void CleanupLogger() {
auto provider = logs_api::Provider::GetLoggerProvider();
if (provider) {
static_cast<logs_sdk::LoggerProvider*>(provider.get())->ForceFlush();
}
std::shared_ptr<logs_api::LoggerProvider> none;
logs_api::Provider::SetLoggerProvider(none);
}
int main() {
InitLogger();
auto logger = logs_api::Provider::GetLoggerProvider()
->GetLogger("myservice", "1.0.0");
logger->EmitLogRecord(logs_api::Severity::kInfo, "Application started");
CleanupLogger();
return 0;
}