Using X-ray(Distribute Tracing ) with Nuxt
Server2022-08-23 17:27 (KST) (Update : 2022-08-30 23:04)
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.