Add new telemetry app #7
|
@ -0,0 +1 @@
|
||||||
|
#default_app_config = "telemetry.apps.TelemetryConfig"
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
|
@ -0,0 +1,78 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import multiprocessing
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
|
from opentelemetry import trace, metrics
|
||||||
|
from opentelemetry._logs import set_logger_provider
|
||||||
|
from opentelemetry.sdk.resources import Resource, SERVICE_INSTANCE_ID
|
||||||
|
|
||||||
|
from opentelemetry.sdk.trace import TracerProvider
|
||||||
|
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
||||||
|
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
|
||||||
|
|
||||||
|
from opentelemetry.sdk.metrics import MeterProvider
|
||||||
|
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
|
||||||
|
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
|
||||||
|
|
||||||
|
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
|
||||||
|
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
|
||||||
|
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter
|
||||||
|
from opentelemetry.instrumentation.django import DjangoInstrumentor
|
||||||
|
|
||||||
|
class TelemetryConfig(AppConfig):
|
||||||
|
name = "telemetry"
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
# Resource Definition
|
||||||
|
resource = Resource.create({
|
||||||
|
"service.name": "development-kitchen",
|
||||||
|
SERVICE_INSTANCE_ID: str(uuid4()),
|
||||||
|
"worker": os.getpid(), # os.getpid() works outside Gunicorn too
|
||||||
|
})
|
||||||
|
|
||||||
|
endpoint = os.environ.get("OTEL_EXPORTER_OTLP_ENDPOINT", "http://129.159.229.69:4317")
|
||||||
|
|
||||||
|
# TRACE SETUP
|
||||||
|
if not isinstance(trace.get_tracer_provider(), TracerProvider):
|
||||||
|
tracer_provider = TracerProvider(resource=resource)
|
||||||
|
span_exporter = OTLPSpanExporter(endpoint=endpoint)
|
||||||
|
tracer_provider.add_span_processor(BatchSpanProcessor(span_exporter))
|
||||||
|
trace.set_tracer_provider(tracer_provider)
|
||||||
|
|
||||||
|
# METRIC SETUP
|
||||||
|
if not isinstance(metrics.get_meter_provider(), MeterProvider):
|
||||||
|
metric_reader = PeriodicExportingMetricReader(OTLPMetricExporter(endpoint=endpoint))
|
||||||
|
meter_provider = MeterProvider(resource=resource, metric_readers=[metric_reader])
|
||||||
|
metrics.set_meter_provider(meter_provider)
|
||||||
|
|
||||||
|
# LOGGING SETUP
|
||||||
|
# 1. Create and set the logger provider FIRST
|
||||||
|
logger_provider = LoggerProvider(resource=resource)
|
||||||
|
set_logger_provider(logger_provider) # MUST be set before using LoggingHandler
|
||||||
|
|
||||||
|
# 2. Add processor and exporter
|
||||||
|
log_exporter = OTLPLogExporter(endpoint=endpoint)
|
||||||
|
logger_provider.add_log_record_processor(BatchLogRecordProcessor(log_exporter))
|
||||||
|
|
||||||
|
# 3. Now safely create the handler (uses global logger provider)
|
||||||
|
otel_handler = LoggingHandler(level=logging.INFO)
|
||||||
|
|
||||||
|
# 4. Attach to Django and root loggers
|
||||||
|
logging.getLogger("django").addHandler(otel_handler)
|
||||||
|
logging.getLogger("django").setLevel(logging.INFO)
|
||||||
|
|
||||||
|
logging.getLogger().addHandler(otel_handler)
|
||||||
|
logging.getLogger().setLevel(logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
from opentelemetry.instrumentation.django import DjangoInstrumentor
|
||||||
|
DjangoInstrumentor().instrument()
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from .utils import PrintLogger # assuming PrintLogger is defined in telemetry/utils.py
|
||||||
|
|
||||||
|
# Redirect print() and errors to logger so they appear in SigNoz
|
||||||
|
sys.stdout = PrintLogger(logging.INFO)
|
||||||
|
sys.stderr = PrintLogger(logging.ERROR)
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
|
@ -0,0 +1,16 @@
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class PrintLogger:
|
||||||
|
def __init__(self, level=logging.INFO):
|
||||||
|
self.logger = logging.getLogger("stdout_redirect")
|
||||||
|
self.level = level
|
||||||
|
self.terminal = sys.__stdout__ # Save original stdout
|
||||||
|
|
||||||
|
def write(self, message):
|
||||||
|
message = message.strip()
|
||||||
|
if message: # avoid empty lines
|
||||||
|
self.logger.log(self.level, message)
|
||||||
|
self.terminal.write(message + '\n') # Echo to terminal
|
||||||
|
def flush(self):
|
||||||
|
self.terminal.flush()
|
|
@ -0,0 +1,3 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
# Create your views here.
|
Loading…
Reference in New Issue