Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#258] ActiveTrace with TransactionId #259

Merged
merged 1 commit into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions lib/client/grpc-data-sender.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,10 @@ class GrpcDataSender {
this.agentInfoDailyScheduler = new Scheduler(this.agentInfoRefreshInterval())
}

initializeProfilerClients(collectorIp, collectorTcpPort, config) {
initializeProfilerClients(collectorIp, collectorTcpPort) {
const profilerBuilder = new OptionsBuilder()
.addInterceptor(makeAgentInformationMetadataInterceptor(this.agentInfo))

if (config && config.grpcServiceConfig && typeof config.grpcServiceConfig.getProfiler === 'function') {
profilerBuilder.setGrpcServiceConfig(config.grpcServiceConfig.getProfiler())
}
this.profilerClient = new services.ProfilerCommandServiceClient(collectorIp + ":" + collectorTcpPort, grpc.credentials.createInsecure(), profilerBuilder.build())
}

Expand Down
7 changes: 5 additions & 2 deletions lib/context/trace-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const log = require('../utils/logger')
const sampler = require('../sampler/sampler')
const DisableTrace = require('./disable-trace')
const localStorage = require('../instrumentation/context/local-storage')
const activeRequestRepository = require('./trace/active-request-repository')
const TraceSampler = require('./trace/trace-sampler')
const SpanBuilder = require('./span-builder')
const SpanChunkBuilder = require('./span-chunk-builder')
Expand All @@ -24,6 +23,7 @@ const AsyncSpanChunkBuilder = require('./trace/async-span-chunk-builder')
const ChildTraceBuilder = require('./trace/child-trace-builder')
const DisableChildTrace = require('./trace/disable-child-trace')
const disableAsyncId = require('./trace/disable-async-id')
const ActiveTraceRepository = require('../metric/active-trace-repository')

class TraceContext {
constructor(agentInfo, dataSender, config) {
Expand All @@ -35,6 +35,7 @@ class TraceContext {
this.enableSampling = config.sampling
}
this.traceSampler = new TraceSampler(agentInfo, config)
this.activeRequestRepository = new ActiveTraceRepository()
}

getAgentInfo() {
Expand Down Expand Up @@ -82,6 +83,7 @@ class TraceContext {
}
try {
trace.close()
this.activeRequestRepository.remove(trace.getTraceRoot())
// activeTrace.remove(trace)
} catch (e) {
log.error('Fail to complete trace object', e)
Expand Down Expand Up @@ -116,7 +118,7 @@ class TraceContext {
}

newLocalTrace(traceRoot) {
activeRequestRepository.registry(traceRoot)
this.activeRequestRepository.register(traceRoot)
return new DisableTrace(traceRoot)
}

Expand All @@ -135,6 +137,7 @@ class TraceContext {
const spanBuilder = new SpanBuilder(traceRoot)
const spanChunkBuilder = new SpanChunkBuilder(traceRoot)
const repository = new SpanRepository(spanChunkBuilder, this.dataSender, this.agentInfo)
this.activeRequestRepository.register(traceRoot)
return new Trace2(spanBuilder, repository)
}

Expand Down
23 changes: 0 additions & 23 deletions lib/context/trace/active-request-repository.js

This file was deleted.

1 change: 0 additions & 1 deletion lib/context/trace/child-trace-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

'use strict'

const SpanEventRecorder = require('./span-event-recorder2')
const TraceRootSpanRecorder = require('./trace-root-span-recorder')
const StackId = require('./stack-id')
const CallStack = require('./call-stack')
Expand Down
32 changes: 32 additions & 0 deletions lib/metric/active-trace-repository.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Pinpoint Node.js Agent
* Copyright 2020-present NAVER Corp.
* Apache License v2.0
*/

'use strict'

const SimpleCache = require('../utils/simple-cache')

// DefaultActiveTraceRepository.java
class ActiveTraceRepository {
constructor() {
this.activeTraceCache = new SimpleCache()
}

register(localTraceRoot) {
const id = localTraceRoot.getTransactionId()
if (typeof id !== 'string' || id.length < 1) {
return
}

this.activeTraceCache.put(id, localTraceRoot)
}

remove(localTraceRoot) {
const id = localTraceRoot.getTransactionId()
this.activeTraceCache.delete(id)
}
}

module.exports = ActiveTraceRepository
48 changes: 45 additions & 3 deletions test/stats/active-trace.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const activeTrace = require('../../lib/metric/active-trace')
const agent = require('../support/agent-singleton-mock')
const express = require('express')
const http = require('http')
const grpc = require('@grpc/grpc-js')
const services = require('../../lib/data/v1/Service_grpc_pb')
const spanMessages = require('../../lib/data/v1/Span_pb')

const TEST_ENV = {
host: 'localhost',
Expand All @@ -37,9 +40,9 @@ test(`Should record active trace in multiple call`, function (t) {

const server = app.listen(TEST_ENV.port, async function () {
Promise.all([
axios.get(getServerUrl(PATH), { httpAgent: new http.Agent({ keepAlive: false })}),
axios.get(getServerUrl(PATH), { httpAgent: new http.Agent({ keepAlive: false })}),
axios.get(getServerUrl(LASTONE_PATH), { httpAgent: new http.Agent({ keepAlive: false })}),
axios.get(getServerUrl(PATH), { httpAgent: new http.Agent({ keepAlive: false }) }),
axios.get(getServerUrl(PATH), { httpAgent: new http.Agent({ keepAlive: false }) }),
axios.get(getServerUrl(LASTONE_PATH), { httpAgent: new http.Agent({ keepAlive: false }) }),
]).then((result) => {
t.equal(activeTrace.getAllTraces().length, 0)
t.equal('' + agent.mockAgentStartTime, agent.agentInfo.startTimestamp, "startTimestamp equals")
Expand All @@ -54,4 +57,43 @@ test(`Should record active trace in multiple call`, function (t) {

t.equal(agent.mockAgentId, fixture.config.agentId, "Agent ID equals")
t.equal(agent.agentInfo, agent.pinpointClient.agentInfo, "AgentInfo equals")
})

test(`Active trace should be recorded with HTTP call`, function (t) {
const collectorServer = new grpc.Server()
collectorServer.addService(services.MetadataService, {
requestApiMetaData: (call, callback) => {
const result = new spanMessages.PResult()
callback(null, result)
}
})
collectorServer.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (err, port) => {
agent.bindHttpWithCallSite(port)

const app = new express()
app.get('/active-trace', async (req, res) => {
agent.callbackTraceClose((trace) => {
const actualCached = agent.getTraceContext().activeRequestRepository.activeTraceCache.get(trace.getTraceRoot().getTransactionId())
t.equal(actualCached, trace.getTraceRoot(), 'active trace traceRoot is cached')
})
setTimeout(() => {
res.send('ok get')
}, 1000)
})

const server = app.listen(TEST_ENV.port, async () => {
const result = await axios.get(getServerUrl('/active-trace'), { httpAgent: new http.Agent({ keepAlive: false }) })
t.equal(result.status, 200, 'status code is 200')
server.close(() => {
const cacheSize = agent.getTraceContext().activeRequestRepository.activeTraceCache.cache.size
t.equal(cacheSize, 0, 'active trace cache is empty')
t.end()
})
})
})
t.teardown(() => {
collectorServer.tryShutdown(() => {

})
})
})
1 change: 1 addition & 0 deletions test/support/agent-singleton-mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class MockAgent extends Agent {
if (sampler.getSamplingCountGenerator()) {
sampler.getSamplingCountGenerator().reset()
}
this.traceContext.activeRequestRepository.activeTraceCache.cache.clear()
transactionIdGenerator.reset()

httpShared.clearPathMatcher()
Expand Down