In the world of software development, log management plays a crucial role in understanding the behavior of applications and detecting potential issues. Vector is an open source project currently maintained by DataDog that provides robust capability for collecting, transforming, and routing logs. OpenTelemetry is an observability framework that simplifies the process of collecting, processing, and exporting telemetry data, including logs, from within your application through the use of SDKs. In this article, we will explore a simple example of sending logs to Vector using the Python OpenTelemetry SDK.
Let’s first start by getting Vector running. The Vector project lives at https://github.com/vectordotdev/vector where all the releases and documentation can be found. Under releases, download the version your machine requires and update the config to look something like below.
[sources.otel]
type = "opentelemetry"
[sources.otel.grpc]
address = "0.0.0.0:4317"
[sources.otel.http]
address = "0.0.0.0:4318"
[sinks.my_sink_id]
type = "console"
inputs = [ "otel.logs" ]
This configuration is creating an OpenTelemetry “source”, which is an OTLP endpoint we’ll send our logs to. The output, or “sink”, in this case is just the console. I recommend looking at Vector’s docs on their available sources, transforms, and sinks, because there’s a lot of them. They really make this easy for you. For the lazy, here’s a link to the list https://vector.dev/components/.
Now to run Vector we just run the below command, replacing the config file path with the path to your updated configuration file.
vector --config vector.toml
With Vector running it’s time to send some logs to it. We’re going to do this in Python, but there’s OpenTelemetry SDKs for just about every mainstream language on OpenTelemetry’s GitHub page (https://github.com/open-telemetry). Let’s get some dependencies installed first.
pip3 install opentelemetry-api
pip3 install opentelemetry-sdk
pip3 install opentelemetry-exporter-otlp
Now moving onto the Python example script. This basically sets up the built in Python logging module to also log in OTLP format to where ever we tell it to. In this case you should just need to update the OTLP_COLLECTOR
variable with the address and port of your Vector process. From there, logging in this manner will ship logs to your Vector process and they’ll show up in the console.
import logging
from opentelemetry import trace
from opentelemetry._logs import set_logger_provider
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
BatchSpanProcessor,
ConsoleSpanExporter,
)
# SET THIS TO YOUR OTLP COLLECTOR ADDRESS AND PORT
OTLP_COLLECTOR = "127.0.0.1:4317"
trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(ConsoleSpanExporter())
)
logger_provider = LoggerProvider(
resource=Resource.create(
{
"service.name": "otel-python-test",
"service.instance.id": "instance-01",
}
),
)
set_logger_provider(logger_provider)
exporter = OTLPLogExporter(insecure=True,endpoint=OTLP_COLLECTOR)
logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter))
# Set the logging level to decide what levels get sent to Vector
handler = LoggingHandler(level=logging.NOTSET, logger_provider=logger_provider)
# Attach OTLP handler to root logger
logging.getLogger().addHandler(handler)
# Log directly
logging.warning("Jail zesty vixen who grabbed pay from quack.")
logging.error("The five boxing wizards jump quickly.")
# Trace context correlation
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("foo"):
# Do something
logging.error("Hyderabad, we have a major problem.")
logger_provider.shutdown()
This code is actually a simplification of OpenTelemetry’s example that can be found at https://github.com/open-telemetry/opentelemetry-python/blob/main/docs/examples/logs/example.py. At the time of writing this, OpenTelemetry considers their logging support “experimental”. So if you’re having any troubles with the above script, take a look at OpenTelemetry’s example, because it’s likely just a result of a breaking change in one of the dependencies. They tend to keep their examples relatively up to date with any major changes.
With that you now have logs in Vector. Once you have logs in Vector, they can go virtually anywhere. Seriously, read their docs and everything they support, it’s an incredible tool (https://vector.dev/components/).