@uyu423/pinpoint-node-agent
Version:
Pinpoint node agent provided by NAVER (Personalized version)
168 lines (137 loc) • 5.6 kB
JavaScript
/**
* Pinpoint Node.js Agent
* Copyright 2020-present NAVER Corp.
* Apache License v2.0
*/
'use strict'
const instManager = require('./instrumentation/inst-manager')
const traceContext = require('./context/trace-context')
const log = require('./utils/logger')
const stringMetaService = require('./context/string-meta-service')
const apiMetaService = require('./context/api-meta-service')
const Scheduler = require('./utils/scheduler')
const AgentStatsMonitor = require('./metric/agent-stats-monitor')
const getConfig = require('./config').getConfig
const PinpointClient = require('./client/pinpoint-client')
const dataSenderFactory = require('./client/data-sender-factory')
const AgentInfo = require('./data/dto/agent-info')
const agentPackage = require('../package')
const wrapped = Symbol('pinpoint-wrapped-function')
const PinScheduler = require('./metric/ping-scheduler')
class Agent {
constructor (initOptions) {
this.config = getConfig(initOptions)
log.warn('[Pinpoint Agent] Configuration', this.config)
if (!this.config.enable || this.config.enable.toString() !== 'true') {
global.__PINPOINT_ENABLED__ = false
log.warn('[Pinpoint Agent]['+this.config.agentId+'] Disabled')
return
}
global.__PINPOINT_ENABLED__ = true
log.warn('[Pinpoint Agent]['+this.config.agentId+'] Init Started')
const agentId = this.config.agentId
const agentStartTime = Date.now()
this.agentInfo = this.createAgentInfo(this.config, agentStartTime)
this.initializeDataSender()
this.initializePinpointClient();
this.traceContext = traceContext.init(this.agentInfo, this.dataSender, this.config)
stringMetaService.init(this.dataSender)
apiMetaService.init(this.dataSender)
this.startSchedule(agentId, agentStartTime);
this.initailizeSupportModules();
log.warn('[Pinpoint Agent][' + agentId + '] Init Completed')
}
initializeDataSender() {
this.dataSender = dataSenderFactory.create(this.config, this.agentInfo)
this.dataSender.send(this.agentInfo)
}
initailizeSupportModules() {
this.loadedModule = [];
instManager.init(this);
}
initializePinpointClient() {
this.pinpointClient = new PinpointClient(this.config, this.agentInfo, this.dataSender)
}
createTraceObject (requestData) {
return this.traceContext.makeTrace(requestData)
}
currentTraceObject () {
return this.traceContext.currentTraceObject()
}
completeTraceObject (trace) {
this.traceContext.completeTraceObject(trace)
if (trace.span) {
/*
const spanEvent = []
// step1. 우선 비동기 코드 (추후 더미코드) 를 먼저 가져오도록 한다.
const dummyEventMap = trace.span.spanEventList.reduce((map, dummyEvent) => {
if (dummyEvent.serviceType === ServiceTypeCode.callback_dummy) {
map[dummyEvent.nextDummyId] = dummyEvent
}
return map
}, {})
// step2. 콜백코드로 저장된 걸 가져오도록 한다. (순서가 보장 안되기 때문에 해당 과정이 필요하다.. )
const callEvent = trace.span.spanEventList.reduce((map, callbackEvent) => {
if (callbackEvent.dummyId !== null) {
map.push(callbackEvent)
}
return map
}, [])
// step3. 비동기 코드를 순차적으로 우회하며 돌도록 한다.
callEvent.forEach((event) => {
const dummyRecoder = dummyEventMap[event.dummyId]
if (dummyRecoder) {
event.sequence = dummyRecoder.sequence
event.depth = dummyRecoder.depth
//TODO. agent view 에서 문제가 있기에 우선 임의로 넣어둔다. (paas와 논의 필요)
// event.startElapsed = dummyRecoder.startElapsed
// event.elapsedTime = dummyRecoder.elapsedTime
if (event.nextDummyId !== null) {
//TODO. event chaiing인 경우 depth 등을 조정해야한다. 순서가 보장안될 수 있으니.. 차순 변경 후 가도 될 듯
dummyEventMap[event.nextDummyId].sequence = event.sequence + 1
dummyEventMap[event.nextDummyId].depth = event.depth + 1
}
}
})
trace.span.spanEventList.forEach((event) => {
if (event.serviceType !== ServiceTypeCode.callback_dummy) {
spanEvent.push(event)
}
})
trace.span.spanEventList = spanEvent
log.debug('finally->\n', trace.span)
*/
}
}
includedModules (moduleName) {
return !this.loadedModule.includes(moduleName)
}
setModules (moduleName) {
this.loadedModule.push(moduleName)
}
createAgentInfo (config, agentStartTime) {
return AgentInfo.create(config, agentStartTime)
}
startSchedule(agentId, agentStartTime) {
if (this.config.enabledStatsMonitor) {
this.mainScheduler = new Scheduler(5000);
const agentStatsMonitor = new AgentStatsMonitor(this.pinpointClient.dataSender, agentId, agentStartTime)
this.mainScheduler.addJob(() => { agentStatsMonitor.run() })
this.mainScheduler.start();
}
this.pingScheduler = new PinScheduler(this.dataSender)
}
spanEndCallbackWrapper(trace, spanEventRecorder, original) {
if (typeof original !== 'function' || original.name === 'pinpointCallbackWrapper') return original
if (trace && !trace.canSampled()) {
return original
}
original[wrapped] = pinpointCallbackWrapper
return pinpointCallbackWrapper
function pinpointCallbackWrapper() {
const result = original.apply(this, arguments)
return result
}
}
}
module.exports = Agent