Carlos Aguni

Highly motivated self-taught IT analyst. Always learning and ready to explore new skills. An eternal apprentice.


Angular OpenTelemetry

10 Aug 2022 »

Angular Instrumentation

https://signoz.io/blog/opentelemetry-angular/

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { NavbarComponent } from './navbar/navbar.component';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { NavbarInputComponent } from './navbar-input/navbar-input.component';
import {
  OpenTelemetryInterceptorModule,
  OtelColExporterModule,
  CompositePropagatorModule,
} from '@jufab/opentelemetry-angular-interceptor';


@NgModule({
  declarations: [
    AppComponent,
    NavbarComponent,
    HomeComponent,
    AboutComponent,
    NavbarInputComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    OpenTelemetryInterceptorModule.forRoot({
      commonConfig: {
        console: true, // Display trace on console (only in DEV env)
        production: false, // Send Trace with BatchSpanProcessor (true) or SimpleSpanProcessor (false)
        serviceName: 'Angular Sample App', // Service name send in trace
        probabilitySampler: '1',
      },
      otelcolConfig: {
        url: 'http://django-max:4318/v1/traces', // URL of opentelemetry collector
      },
    }),
    //Insert OtelCol exporter module
    OtelColExporterModule,
    //Insert propagator module
    CompositePropagatorModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
npm i @jufab/opentelemetry-angular-interceptor && \
npm i \
    @opentelemetry/api \
    @opentelemetry/sdk-trace-web \
    @opentelemetry/sdk-trace-base \
    @opentelemetry/core \
    @opentelemetry/semantic-conventions \
    @opentelemetry/resources \
    @opentelemetry/exporter-trace-otlp-http \
    @opentelemetry/exporter-zipkin \
    @opentelemetry/propagator-b3 \
    @opentelemetry/propagator-jaeger \
    @opentelemetry/context-zone-peer-dep \
    @opentelemetry/instrumentation \
    @opentelemetry/instrumentation-document-load \
    @opentelemetry/instrumentation-fetch \
    @opentelemetry/instrumentation-xml-http-request \
    @opentelemetry/propagator-aws-xray --save-dev


https://opentelemetry.io/docs/collector/getting-started/

setup

git clone https://github.com/open-telemetry/opentelemetry-collector-contrib.git
cd opentelemetry-collector-contrib/examples/demo
git clone https://github.com/SigNoz/sample-angular-app.git

https://jufab.github.io/opentelemetry-angular-webpack-interceptor/

start otel stack

git clone https://github.com/open-telemetry/opentelemetry-collector-contrib.git
cd opentelemetry-collector-contrib/examples/demo/

allow cors https://github.com/jaegertracing/jaeger/issues/2039

docker run -dit --name jaeger \
    -p 16686:16686 \
    -p 14268:14268 \
    jaegertracing/all-in-one:latest \
    --query.additional-headers "access-control-allow-origin: *"
docker run -dit --name jaeger \
    -p 16686:16686 \
    -p 14268:14268 \
    -p 4318:4318 \
    jaegertracing/all-in-one:latest \
    --collector.otlp.enabled=true \
    --query.additional-headers "access-control-allow-origin: *"
version: "2"
services:

  # Jaeger
  jaeger-all-in-one:
    image: jaegertracing/all-in-one:latest
    ports:
      - "16686:16686"
      - "14268"
      - "14250"

  # Collector
  otel-collector:
    image: ${OTELCOL_IMG}
    command: ["--config=/etc/otel-collector-config.yaml", "${OTELCOL_ARGS}"]
    volumes:
      - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
    ports:
      - "1888:1888"   # pprof extension
      - "8888:8888"   # Prometheus metrics exposed by the collector
      - "8889:8889"   # Prometheus exporter metrics
      - "13133:13133" # health_check extension
      - "4317:4317"   # OTLP gRPC receiver
      - "4318:4318"   # OTLP gRPC receiver
      - "55679:55679" # zpages extension
    depends_on:
      - jaeger-all-in-one

otel-collector-config.yml

receivers:
  otlp:
    protocols:
      grpc:
      http:
        cors:
           allowed_origins:
             - http://django-max:8080

exporters:
    #prometheus:
    #  endpoint: "0.0.0.0:8889"
    #  const_labels:
    #    label1: value1

  logging:

    #zipkin:
    #  endpoint: "http://zipkin-all-in-one:9411/api/v2/spans"
    #  format: proto

  jaeger:
    endpoint: jaeger-all-in-one:14250
    tls:
      insecure: true

processors:
  batch:

extensions:
  health_check:
  pprof:
    endpoint: :1888
  zpages:
    endpoint: :55679

service:
  extensions: [pprof, zpages, health_check]
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      #exporters: [logging, zipkin, jaeger]
      exporters: [jaeger, logging]
      #exporters: [logging]
      #metrics:
      #  receivers: [otlp]
      #  processors: [batch]
      #  exporters: [logging, prometheus]

python auto instrumentation not pushing traces

https://github.com/open-telemetry/opentelemetry-python/issues/2761

Working flask instrumentation

https://www.logicmonitor.com/blog/flask-application-manual-instrumentation-for-distributed-traces?utm_medium=organic-social&utm_source=everyonesocial&utm_term=na&utm_content=na&utm_campaign=2021_Organic-Social-EveryoneSocial_Blog&es_id=521eb4aa57


export LM_OTEL_ENDPOINT=http://10.7.0.24:4317

export OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry,service.name=instrument-flask-app,host.name=localhost


pip install flask
pip install opentelemetry-api
pip install opentelemetry-sdk
pip install opentelemetry-instrumentation-flask
pip install opentelemetry-exporter-otlp

app.py

from flask import Flask, jsonify, request
from flask_cors import CORS
from opentelemetry import trace
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor,ConsoleSpanExporter
import os

app = Flask(__name__) 
CORS(app)
FlaskInstrumentor().instrument_app(app)
trace.set_tracer_provider(TracerProvider())



# To print the traces on the console
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))

# To send the traces to the configured OTEL collector
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(
OTLPSpanExporter(endpoint=os.environ.get("LM_OTEL_ENDPOINT"), insecure=True)))

@app.route("/")  
def hello():  
    return jsonify({"a": 2})
    return "Hello World!"  


if __name__ == "__main__":  
   app.run(port=8081, host='0.0.0.0')