Otel

 avatar
unknown
java
2 years ago
3.8 kB
6
Indexable
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.GlobalMeterProvider;
import io.opentelemetry.api.metrics.LongTaskResult;
import io.opentelemetry.api.metrics.LongTaskUpdate;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.LongTaskStart;
import io.opentelemetry.api.metrics.common.Labels;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BinaryTree {

    private static final Lock lock = new ReentrantLock();
    private static final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();

    private Node root;

    // Initialize OpenTelemetry components
    private static final Tracer tracer = OpenTelemetry.getGlobalTracer("com.example.BinaryTree");
    private static final Meter meter = GlobalMeterProvider.getMeter("com.example.BinaryTree");

    // Register a long task to compute CPU usage during the add operation
    private final LongTaskResult addCpuUsageResult = meter.longTaskBuilder("add_cpu_usage")
            .setDescription("CPU usage of the add method")
            .setUnit("ns")
            .build()
            .start();

    // Define the LongTaskStart and LongTaskUpdate functions outside of the add() method
    private final LongTaskUpdate addCpuUsageUpdate = new LongTaskUpdate() {
        @Override
        public void update(long durationNanos, LongTaskResult result) {
            Labels labels = Labels.of("thread_name", Thread.currentThread().getName());
            result.observe(durationNanos, labels);
        }
    };

    private final LongTaskStart addCpuUsageStart = new LongTaskStart() {
        @Override
        public void start(Attributes attributes, LongTaskResult result) {
            // Do nothing
        }
    };

    public BinaryTree() {}

    public void add(int value) {
        Span span = tracer.spanBuilder("add").startSpan();
        try (Scope scope = span.makeCurrent()) {
            span.addEvent("Starting add method");
            long taskId = addCpuUsageResult.getTaskId();
            long startCpuTime = threadMXBean.getCurrentThreadCpuTime();
            lock.lock();
            try {
                // Perform the actual addition of the element
                root = addRecursive(root, value);

                // Store the result of the long task in an attribute
                addCpuUsageResult.stop();
                meter.longTaskBuilder("add_cpu_usage_callback")
                        .setDescription("CPU usage of the add method with a callback")
                        .setUnit("ns")
                        .build()
                        .observe(addCpuUsageUpdate, addCpuUsageStart, addCpuUsageResult);

                Attributes attributes = Attributes.of("long_task", addCpuUsageResult);
                span.addEvent("Element added successfully", attributes);

            } finally {
                lock.unlock();
            }
            long endCpuTime = threadMXBean.getCurrentThreadCpuTime();
            long duration = endCpuTime - startCpuTime;
            Attributes attributes = Attributes.of("cpu_time", duration);
            span.addEvent("Ending add method", attributes);
            span.setStatus(Span.Status.OK);
        } catch (Exception e) {
            span.setStatus(Span.Status.ERROR);
            span.recordException(e);
        } finally {
            span.end();
        }
    }

    private Node addRecursive(Node current, int value) {
        if (current == null) {
            return new Node