在 EC2 上的 Kubernetes 上为我的微服务部署试用 AWS 新服务 X-RAY。这是我看到的日志:
root@internal-reporting-test-1680758663-3gweh:/usr/src/app# cat AWSXRay.log
2016-12-06 04:36:23.5840 +00:00 [INFO] UDP message sent: {"trace_id":"1-58464048-03fbcdf5c861f95fc5204ec6","id":"105107e6c9df4bfe","start_time":1480998983.553,"name":"localhost","http":{"request":{"method":"GET","user_agent":"curl/7.38.0","client_ip":"127.0.0.1","url":"http://localhost"},"response":{"status":404,"content_length":0}},"service":{"version":"1.0.0"},"error":true,"end_time":1480998983.574}
2016-12-06 04:36:33.2560 +00:00 [INFO] UDP message sent: {"trace_id":"1-58464051-3e3799a566c0933093f51b7a","id":"94d4267609d2ba40","start_time":1480998993.205,"name":"localhost","http":{"request":{"method":"GET","user_agent":"curl/7.38.0","client_ip":"127.0.0.1","url":"http://localhost"},"response":{"status":200,"content_length":0}},"service":{"version":"1.0.0"},"end_time":1480998993.252}
2016-12-06 04:36:35.5810 +00:00 [INFO] UDP message sent: {"trace_id":"1-58464054-5df1e9ec46ef2b26b2d29965","id":"113fd36cddb5de95","start_time":1480998995.552,"name":"localhost","http":{"request":{"method":"GET","user_agent":"curl/7.38.0","client_ip":"127.0.0.1","url":"http://localhost"},"response":{"status":200,"content_length":0}},"service":{"version":"1.0.0"},"end_time":1480998995.579}
2016-12-06 04:36:41.3350 +00:00 [INFO] UDP message sent: {"trace_id":"1-58464059-0dfd2e274ca20499c6bce17f","id":"1dfac818142b2d28","start_time":1480999001.304,"name":"localhost","http":{"request":{"method":"GET","user_agent":"curl/7.38.0","client_ip":"127.0.0.1","url":"http://localhost"},"response":{"status":200,"content_length":0}},"service":{"version":"1.0.0"},"end_time":1480999001.332}
我正在使用的卷曲:
# curl localhost/v1/internal/report/users
主管会议:
[supervisord]
nodaemon=true
[program:xray]
command=/usr/src/app/xray
[program:npm]
command=npm start
用于表达与 hapi 一起使用的中间件的 Mod:
/**
* Express_mw module.
*
* Exposes middleware functions to enable automated data capturing on a web service. To enable on a Node.js/Express application,
* use 'app.use(AWSXRay.express.openSegment())' before defining your routes. After your routes, before any extra error
* handling middleware, use 'app.use(AWSXRay.express.closeSegment())'.
* Use AWSXRay.getSegment() to access the current segment/subsegment.
* Otherwise, for manual mode, this appends the Segment object to the request object as req.segment.
* @module express_mw
*/
var _ = require('underscore');
var CLSUtils = require('../utils').CLSUtils;
var MWUtils = require('./mw_utils');
var Local = require('../segments/attributes/local');
var Segment = require('../segments/segment');
var getCauseType = require('../utils').getCauseTypeFromHttpStatus;
var XRAY_HEADER = 'x-amzn-trace-id';
var NAME = process.env.XRAY_TRACING_NAME;
var DEFAULT_NAME = process.env.XRAY_TRACING_DEFAULT_NAME;
/**
* Use 'app.use(AWSXRay.express.openSegment())' before defining your routes.
* Use AWSXRay.getSegment() to access the current segment/subsegment.
* Otherwise, for manual mode, this appends the Segment object to the request object as req.segment.
* @alias module:express_mw.openSegment
* @returns {function}
*/
module.exports.openSegment = function openSegment() {
if (_.isUndefined(DEFAULT_NAME) && _.isUndefined(MWUtils.defaultName)) {
throw new Error('Default segment name must be set using "process.env.XRAY_TRACING_DEFAULT_NAME"' +
' or "setDefaultName()".');
}
return function open(request, next) {
/*
* Get the true HTTP objects
*/
req = request.raw.req;
res = request.raw.res;
var amznTraceHeader = processHeaders(req);
var segment = new Segment(resolveName(req.headers.host), amznTraceHeader.Root, amznTraceHeader.Parent);
resolveSampling(amznTraceHeader, segment, res);
segment.addAttribute('http', new Local(req));
MWUtils.populate(segment);
res.on('finish', function () {
if (this.statusCode === 429)
segment.addThrottle();
else if (getCauseType(this.statusCode))
segment[getCauseType(this.statusCode)] = true;
segment.http.close(this);
segment.close();
});
if (CLSUtils.isCLSMode()) {
var ns = CLSUtils.getNamespace();
ns.bindEmitter(req);
ns.bindEmitter(res);
ns.run(function () {
CLSUtils.setSegment(segment);
if (next) { next(); }
});
} else {
req.segment = segment;
if (next) { next(); }
}
};
};
/**
* After your routes, before any extra error handling middleware, use 'app.use(AWSXRay.express.closeSegment())'.
* @alias module:express_mw.closeSegment
* @returns {function}
*/
module.exports.closeSegment = function closeSegment() {
return function close(request, next) {
req = request.raw.req;
res = request.raw.res;
var segment = CLSUtils.isCLSMode() ? CLSUtils.getSegment() : segment = req.segment;
if (segment && err) {
segment.counter = 0;
segment.close(err);
} else if (segment) {
segment.close();
}
if (next)
next(err);
};
};
function processHeaders(req) {
var amznTraceHeader = {};
if (req && req.headers && req.headers[XRAY_HEADER]) {
_.each(req.headers[XRAY_HEADER].replace(/ /g,'').split(';'), function (header) {
var pair = header.split('=');
this[pair[0]] = pair[1];
}, amznTraceHeader);
}
return amznTraceHeader;
}
function resolveName(hostName) {
if (NAME)
return NAME;
var regex = new RegExp('(?:[0-9]{1,3}\.){3}[0-9]{1,3}', 'g');
var hostIp = hostName.match(regex) || _.isEmpty(hostName);
return !hostIp ? hostName : (DEFAULT_NAME ? DEFAULT_NAME : MWUtils.defaultName);
}
function resolveSampling(amznTraceHeader, segment, res) {
var isSampled;
if (amznTraceHeader.Sampled === '1')
isSampled = true;
else if (amznTraceHeader.Sampled === '0')
isSampled = false;
isSampled = !_.isUndefined(isSampled) ? isSampled : MWUtils.shouldSample();
if (amznTraceHeader.Sampled === '?')
res.header[XRAY_HEADER] = 'Root=' + amznTraceHeader.Root + '; Sampled=' + (isSampled ? '1' : '0');
if (!isSampled)
segment.notTraced = true;
}
使用此服务时,更改相对简单。只是将原始节点 HTTP 对象强制发送到中间件。
日志显示对 xray 服务的 UDP 请求正在按预期工作。然而在控制台中我没有看到任何结果。
有人有想法么?