Using X-ray(Distribute Tracing ) with Nuxt

Server

(Update : 2022-08-30)

Language :

Hi, i’am Lovefield.

The development structure has been microserviceized as it moved to Nuxt. As it becomes a microservices, the request is executed in the order of 'front-end -> api -> back-end' when accessing the site. At least 3 requests must be combined to display one page, and this article is how to connect AWS x-rays.

First add "server middleware" and Axios config to Nuxt.

…
modules: ["@nuxtjs/axios"],

axios:{
    proxy: true
},

proxy: {
       "/api/": {
           target: "BACKEND-URL",
           pathRewrite: {
               "^/api/": "/api/v1/",
           },
       },
   },

serverMiddleware : ["serverMiddleware/x-ray"]

The client requests the front-end server for the screen and the API. So, write the code, remembering that you need to separate the two. Create the file "x-ray.js" in the "serverMiddleware" folder.

// The x-ray uses the "dgram"(Node default Module) module because it communicates using the socket.
import dgram from "dgram";

// Must be 16 digits, consisting of functions a to f + 0 to 9 for generating separator IDs.
function createRequestId() {
   let possible = "abcdef0123456789";
   let text = "";
   for (let i = 0; i < 16; i += 1) {
       text += possible.charAt(Math.floor(Math.random() * possible.length));
   }
   return text;
}

// The actual operating code portion.
export default function (req, res, next) {
   let headers = req && req.headers ? Object.assign({}, req.headers) : {};
   let traceHeader = headers["x-amzn-trace-id"]; // aws is always add “x-amzn-trace-id” value in header.
   let requestURL = req.url;
   let apiReg = new RegExp("\\/api", "i");

   if (traceHeader !== undefined) {
       let server = dgram.createSocket("udp4");
       let requestDate = new Date().getTime() / 1000;
       let requestId = createRequestId();
       let isApiRequest = apiReg.test(requestURL);
       let traceId = traceHeader.substr(5, 35);

       if (isApiRequest == false) { // if api request add data to req. (used in axios plugin)
           req.requestId = requestId;
           req.traceId = traceId;
       }

       // action in finish response
       res.on("finish", () => {
           let jsonData = {
               name: `appname`,
               id: requestId,
               origin: "AWS::EC2::Instance",
               trace_id: traceId,
               start_time: requestDate,
               end_time: new Date().getTime() / 1000,
               http: {
                   request: {
                       url: req.url,
                       method: req.method,
                       user_agent: headers["user-agent"],
                       x_forwarded_for: true,
                   },
                   response: {
                       status: res.statusCode,
                   },
               },
           };

           if (isApiRequest == true) {
               jsonData.type = "subsegment";
               jsonData.parent_id = headers["requestid"];
           }

           let message = Buffer.from(`{"format": "json", "version": 1}\n` + JSON.stringify(jsonData));

           server.send(message, 2000,"localhost", (err) => { // x-ray is send data to localhost.
               server.close();
           });
       });
   }

   next();
}

The default operating code is as above.
Now we add settings to the axios plugin.

export default function ({ req, $axios }) {
   let requestId = req ? req.requestId : undefined;

   $axios.onRequest((config) => {
       if (requestId !== undefined) {
           config.headers.common["requestid"] = requestId;
           config.headers.common["X-Amzn-Trace-Id"] = `Root=${req.traceId};Parent=${requestId}`;
       }
   });
}

If there is a 'requestId' set in 'x-ray.js' when making a request, add the corresponding value to the API request.

I'm done setting up the app. Now you need to access the AWS instance and run the x-ray.After installing x-ray on the instance, check the status with 'sudo service xray start' and then 'sudo service xray status'.

You can view x-ray recordings in CludWatch -> x-ray recordings.

Lovefield

Web Front-End developer

하고싶은게 많고, 나만의 서비스를 만들고 싶은 변태스러운 개발자입니다.