diff --git a/modules/nodejs-agent/lib/plugins/plugin-manager.js b/modules/nodejs-agent/lib/plugins/plugin-manager.js index 7b6e366..bb0b80c 100644 --- a/modules/nodejs-agent/lib/plugins/plugin-manager.js +++ b/modules/nodejs-agent/lib/plugins/plugin-manager.js @@ -19,7 +19,7 @@ module.exports = PluginManager; const logger = require("../logger"); -const OFFICER_SUPPORTED_MODULE = ["mysql", "http", "egg-core", "egg", "amqp"]; +const OFFICER_SUPPORTED_MODULE = ["mysql", "http", "egg-core", "egg", "amqp","socket.io"]; /** * diff --git a/modules/nodejs-agent/lib/plugins/socket.io/client.js b/modules/nodejs-agent/lib/plugins/socket.io/client.js new file mode 100755 index 0000000..3ce45f4 --- /dev/null +++ b/modules/nodejs-agent/lib/plugins/socket.io/client.js @@ -0,0 +1,57 @@ +/* + * Licensed to the SkyAPM under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +"use strict"; + +const ContextCarrier = require("skyapm-nodejs/lib/trace/context-carrier"); +const layerDefine = require("skyapm-nodejs/lib/trace/span-layer"); +const componentDefine = require("skyapm-nodejs/lib/trace/component-define"); +var parser = require('socket.io-parser'); +/** + * + * @param {socketioModule} socketioModule + * @param {instrumentation} instrumentation + * @param {contextManager} contextManager + * @return {*} + * @author Quanjie.Deng + */ +module.exports = function(socketioModule, instrumentation, contextManager) { + instrumentation.enhanceMethod(socketioModule, "ondecoded", wrapOndecoded); + return socketioModule; + + function wrapOndecoded(original) { + return function(packet) { + let contextCarrier = new ContextCarrier(); + if(packet.data.hasOwnProperty("headers")){ + contextCarrier.fetchBy(function(key) { + if (packet.data.headers.hasOwnProperty(key)) { + return packet.data.headers[key]; + } + return undefined; + }); + } + + let opName = packet.nsp+packet.data[0]; + let span = contextManager.createEntrySpan(opName, contextCarrier); + span.component(componentDefine.Components.SOCKETIO); + span.spanLayer(layerDefine.Layers.HTTP); + let result = original.apply(this,arguments); + contextManager.finishSpan(span); + return result; + }; + } + +} diff --git a/modules/nodejs-agent/lib/plugins/socket.io/index.js b/modules/nodejs-agent/lib/plugins/socket.io/index.js new file mode 100755 index 0000000..5ff0b7c --- /dev/null +++ b/modules/nodejs-agent/lib/plugins/socket.io/index.js @@ -0,0 +1,35 @@ +/* + * Licensed to the SkyAPM under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +"use strict"; + +const Plugin = require("skyapm-nodejs/lib/plugins/plugin"); + +module.exports = new Plugin("socket.io-plugin", "socket.io", [{ + _name: "socket.io", + _description: "Enhance all version of socket.io module", + _enhanceModules: ["client"], + canEnhance: function(version, enhanceFile) { + if (this._enhanceModules.indexOf(enhanceFile) > -1) { + return true; + } + return false; + }, + getInterceptor: function(enhanceFile) { + return require("./" + enhanceFile); + }, +}]); diff --git a/modules/nodejs-agent/lib/trace/component-define.js b/modules/nodejs-agent/lib/trace/component-define.js index d1f5540..77aa486 100644 --- a/modules/nodejs-agent/lib/trace/component-define.js +++ b/modules/nodejs-agent/lib/trace/component-define.js @@ -40,6 +40,7 @@ let Components = function() { this.MYSQL = new OfficeComponent(5, "MYSQL"); this.EGG = new OfficeComponent(4003, "Egg"); this.AMQP = new OfficeComponent(4004, "AMQP"); + this.SOCKETIO = new OfficeComponent(4005, "SOCKET.IO"); }; Components.instance = null; diff --git a/modules/nodejs-agent/package.json b/modules/nodejs-agent/package.json index 25ba008..97b8eef 100644 --- a/modules/nodejs-agent/package.json +++ b/modules/nodejs-agent/package.json @@ -43,7 +43,8 @@ "on-finished": "^2.3.0", "randomatic": "^3.1.1", "resolve": "^1.8.1", - "semver": "^5.5.1" + "semver": "^5.5.1", + "socket.io-parser": "~3.4.0" }, "devDependencies": { "cz-conventional-changelog": "^2.1.0",