In today’s microservices, full link tracing seems to be standard. In particular, a standard is emerging from the merger of Open Tracing and Opencensus to become OpentElemetry. But how does full-link tracing work?

All full link tracing that needs to be injected into business code is hooligan.

open telemetry

I’m only using HTTP as an example, but the rest is the same. Opentelemetry works by saying, It no invasion of the {version} – {traceId} – {spanId} – {sampleDecision} (00 – cc8516a5aaea87046a666c18ad82fada – 7 a29ad27e4706769-01) the string into HTTP headers, so that you can do full link tracing, using traceid to associate various HTTP.

Then borrow tools, you can easily show the tracking of the entire link.

But how does OpentElemetry track HTTP without invasively?

Here we have the Node segment and the browser side.

Node.js

Intercepts HTTP/HTTPS modules

The principle of

import https from 'https';

// Implement painless injection by abstracting the following code into a module
const orginRequest = https.request;
https.request = function () {
    console.log('interceptor');
    // There are many things you can do here,
    // 1. Modify the HTTP header and inject the ID of the full link tracing
    // 2. Modify request callback
    return Reflect.apply(orginRequest, this.arguments)}const options = {
    hostname: 'www.baidu.com'.port: 443.path: "/img/PC_7ac6a6d319ba4ae29b38e5e4280e9122.png".method: 'GET'
}
const req = https.request(options, res= > {
    console.log(`statusCode: ${res.statusCode}`)
})
req.end();
Copy the code

Mature implementations are a bit more complicated, and need to consider which packages require Monkey Patches. Methods also need to be replaced in the import phase.

Mature implementation

opentelemetry-instrumentation-http

Opentelemetyle-instrument-http is used in the background.

  1. require-in-the-middle

This package is responsible for replacing modules when importing.

  1. shimmer

Shimmer is responsible for replacing the implementation of concrete methods when replacing modules.

The browser

The server is required to generate the associated ID. It is then later injected into the headers of HTTP requests on the web page.

Intercept the HTTP

The implementation principle is simple: Monkey Patch.

const origin = fetch;
window.fetch = function fn(. args) {
    console.log('inside fetch');
    const url = args[0];
    let opt = args[1) | | {};// Inject the traceparent headeropt.headers = { ... opt.headers,'traceparent': 'test12' };
    const newArgs = [url, opt];
    return Reflect.apply(origin, window, newArgs);
}
btn1.addEventListener('click'.async() = > {console.log("callback....");
    const resp = await fetch("http://localhost:5000/froentend/zonejs/zonejs.html")
    const text = await resp.text();
    console.log(text);
});
Copy the code

Mature implementation

  1. opentelemetry-instrumentation-xml-http-request

  2. opentelemetry-instrumentation-fetch

But if it’s a user click, click event, how do we trace it?

Monitoring User behavior

Again, use Monkey Patch.

function timeUp(fn) {
    const start = performance.now();
    return function (event) {
        const result = Reflect.apply(fn, this.arguments);
        const end = performance.now();
        console.log("time up is ", end - start, performance.now());
        return result;
    }
}

btn1.addEventListener('click', timeUp(() = > {
    let result = 0;
    for (let index = 0; index < 10000; index++) {
        result += index;
    }
    console.log(result, performance.now());
}));

Copy the code

The collected data is then sent to the full-link Logging server.

But this is only synchronous tasks, and if callback has asynchronous tasks, setTimeout/Promise, then it becomes difficult to count the elapsed time of these tasks. Fortunately, these problems can be easily solved with zone.js.

Mature implementation

opentelemetry-instrumentation-user-interaction