Olhe dentro do seu código C++: por que observabilidade não é luxo, mas necessidade
\n\nImagine: você iniciou um serviço de alta carga em C++. Passou uma hora, duas, um dia — tudo voando. E então, puf! — os usuários reclamam de lentidão, e você fica se perguntando: onde está o gargalo? Na memória? Na rede? Ou alguém simplesmente esqueceu de liberar um recurso? Sem um sistema de observabilidade, você é como um capitão de navio com as vigias lacradas. Você sente que algo está errado, mas não vê o que exatamente.
\n\nObservabilidade em C++ é o seu conjunto de periscópios e radares. Não é apenas logging, são três pilares: rastreamento, métricas e logs. Neste artigo, vamos analisar cada um deles com exemplos reais de código, mostrar como integrar C++ com OpenTelemetry e Prometheus, e dar receitas prontas para produção. Vamos nessa!
\n\nOs três pilares da observabilidade: rastreamento, métricas, logs
\n\nAntes de mergulhar no código, vamos definir claramente como esses conceitos diferem e se complementam. Muitos confundem observabilidade com simples logging — e erram. É como comparar uma lanterna com um holofote.
\n\n- \n
- Logs são eventos. "O que aconteceu?" (por exemplo, "Usuário autenticado" ou "Erro de conexão com o BD"). Eles são detalhados, mas sem contexto podem ser inúteis. \n
- Métricas são números. "Quanto?" (quantidade de requisições por segundo, uso de CPU, tempo de resposta). Elas são agregadas e mostram tendências. \n
- Rastreamento é o caminho da requisição. "Como exatamente isso aconteceu?" (da entrada no serviço até a chamada ao banco de dados e a resposta ao cliente). É o elo de ligação entre logs e métricas. \n
A observabilidade ideal em C++ é quando você, olhando para um dashboard, consegue entender em 10 segundos: onde, quando e por que ocorreu uma anomalia. Sem isso, você vai jogar de adivinhação com a produção.
\n\nRastreamento em C++: como implementar OpenTelemetry
\n\nVamos começar com a ferramenta mais poderosa, mas também a mais complexa — o rastreamento. OpenTelemetry é o padrão de facto para coleta de telemetria. Em C++, o suporte não é tão rico quanto em Go ou Java, mas funciona de forma estável.
\n\nSuponha que temos um servidor HTTP simples em C++ (usamos a ideia, não uma biblioteca específica). Precisamos rastrear quanto tempo cada requisição leva para ser processada e quais chamadas ocorrem dentro dela.
\n\nConfiguração do OpenTelemetry em C++
\n\nPrimeiro, instalamos as dependências. No CMakeLists.txt, adicionamos:
\n\nfind_package(opentelemetry-cpp REQUIRED)\ntarget_link_libraries(my_app PRIVATE opentelemetry::api opentelemetry::exporter_ostream)\n\nAgora, criamos um tracer e spans (span é uma unidade de trabalho). Aqui está um exemplo mínimo:
\n\n#include <opentelemetry/trace/provider.h>\n#include <opentelemetry/exporters/ostream/span_exporter.h>\n#include <opentelemetry/sdk/trace/tracer_provider.h>\n#include <opentelemetry/sdk/trace/simple_processor.h>\n\nnamespace trace_api = opentelemetry::trace;\nnamespace trace_sdk = opentelemetry::sdk::trace;\nnamespace trace_exporter = opentelemetry::exporter::trace;\n\nvoid init_tracer() {\n auto exporter = std::unique_ptr<trace_sdk::SpanExporter>(\n new trace_exporter::OStreamSpanExporter(std::cout));\n auto processor = std::unique_ptr<trace_sdk::SpanProcessor>(\n new trace_sdk::SimpleSpanProcessor(std::move(exporter)));\n auto provider = std::make_shared<trace_sdk::TracerProvider>(std::move(processor));\n trace_api::Provider::SetTracerProvider(provider);\n}\n\nvoid process_request(const std::string& user_id) {\n auto tracer = trace_api::Provider::GetTracerProvider()->GetTracer("my_service");\n auto span = tracer->StartSpan("process_request");\n span->SetAttribute("user.id", user_id);\n\n // Simulação de trabalho\n std::this_thread::sleep_for(std::chrono::milliseconds(100));\n\n span->End();\n}\n\nint main