From e8d5834eba20dcf461261b8b3f181114abfac6d9 Mon Sep 17 00:00:00 2001 From: Yongseok Date: Wed, 16 Oct 2024 17:04:21 +0900 Subject: [PATCH] [#226] Implemetations TraceRoot * URL have to create baseURL that To parse the URL into its parts * TraceContext no needs Singleton. It is only a member variable of the agent singleton * Fix a test failure * Fix github actions --- .github/workflows/main.yml | 27 +- lib/agent.js | 4 +- lib/client/grpc-data-sender.js | 7 +- lib/client/grpc-readable-stream.js | 8 +- lib/context/disable-trace.js | 3 +- lib/context/remote-trace-root-builder.js | 43 ++ lib/context/span-builder.js | 26 + lib/context/span-chunk-builder.js | 25 + lib/context/span-chunk.js | 8 +- lib/context/trace-builder.js | 32 + lib/context/trace-context.js | 79 ++- lib/context/trace-root-builder.js | 31 + .../trace/active-request-repository.js | 23 + lib/context/trace/continue-disabled-id.js | 17 + lib/context/trace/id-generator.js | 33 + lib/context/trace/long-id-generator.js | 31 + .../trace/span-event-recorder-builder.js | 25 + lib/context/trace/span-repository.js | 17 + lib/context/trace/trace-id-builder.js | 28 + lib/context/trace/trace-sampler.js | 71 +++ lib/instrumentation/http-shared.js | 5 +- .../http/http-request-trace-builder.js | 56 ++ .../http/trace-header-builder.js | 87 +++ package-lock.json | 592 ++++++++++-------- package.json | 2 +- ...rpc-data-sender-client-side-stream.test.js | 35 +- test/client/grpc-data-sender.test.js | 177 +++--- test/client/grpc-fixture.js | 2 +- test/context/trace-context.test.js | 10 +- test/support/agent-singleton-mock.js | 6 +- test/utils/ant-path-matcher.test.js | 2 +- 31 files changed, 1085 insertions(+), 427 deletions(-) create mode 100644 lib/context/remote-trace-root-builder.js create mode 100644 lib/context/span-builder.js create mode 100644 lib/context/span-chunk-builder.js create mode 100644 lib/context/trace-builder.js create mode 100644 lib/context/trace-root-builder.js create mode 100644 lib/context/trace/active-request-repository.js create mode 100644 lib/context/trace/continue-disabled-id.js create mode 100644 lib/context/trace/id-generator.js create mode 100644 lib/context/trace/long-id-generator.js create mode 100644 lib/context/trace/span-event-recorder-builder.js create mode 100644 lib/context/trace/span-repository.js create mode 100644 lib/context/trace/trace-id-builder.js create mode 100644 lib/context/trace/trace-sampler.js create mode 100644 lib/instrumentation/http/http-request-trace-builder.js create mode 100644 lib/instrumentation/http/trace-header-builder.js diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8b2dc6a9..1617fed9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,12 +35,23 @@ jobs: # path: '**/checkstyle-result.xml' - name: Coverage run: npm run coverage + # Required for generating html artifact, can be skipped if not generating html artifact + # - name: Report coverage + # uses: hrishikesh-kadam/setup-lcov@v1 + # - name: Upload coverage report + # uses: kefasjw/lcov-pull-request-report@v1 + # with: + # # Lcov file location. For example, coverage/lcov.info + # lcov-file: coverage/lcov.info + + # # Github token required for getting list of changed files and posting comments + # github-token: ${{ secrets.GITHUB_TOKEN }} # ... Generate LCOV files or download it from a different job - - name: Setup LCOV - uses: hrishikesh-kadam/setup-lcov@v1 - - name: Report coverage - uses: zgosalvez/github-actions-report-lcov@v3 - with: - coverage-files: coverage/lcov.info - github-token: ${{ secrets.ACTIONS_TOKEN }} - update-comment: true + # - name: Setup LCOV + # uses: hrishikesh-kadam/setup-lcov@v1 + # - name: Report coverage + # uses: zgosalvez/github-actions-report-lcov@v4 + # with: + # coverage-files: coverage/lcov.info + # github-token: ${{ secrets.ACTIONS_TOKEN }} + # update-comment: true diff --git a/lib/agent.js b/lib/agent.js index 65970410..26d2ba9d 100644 --- a/lib/agent.js +++ b/lib/agent.js @@ -7,7 +7,7 @@ 'use strict' const ModuleHook = require('./instrumentation/module-hook') -const traceContext = require('./context/trace-context') +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') @@ -40,7 +40,7 @@ class Agent { this.initializeDataSender() this.initializePinpointClient() - this.traceContext = traceContext.init(this.agentInfo, this.dataSender, this.config) + this.traceContext = new TraceContext(this.agentInfo, this.dataSender, this.config) stringMetaService.init(this.dataSender) apiMetaService.init(this.dataSender) diff --git a/lib/client/grpc-data-sender.js b/lib/client/grpc-data-sender.js index 2156a7d8..c4b85efa 100644 --- a/lib/client/grpc-data-sender.js +++ b/lib/client/grpc-data-sender.js @@ -62,15 +62,16 @@ class GrpcDataSender { if (this.statClient) { this.statClient.close() } + + if (this.profilerClient) { + this.profilerClient.close() + } if (this.commandStream) { this.commandStream.end() } if (this.activeThreadCountStream) { this.activeThreadCountStream.end() } - if (this.profilerClient) { - this.profilerClient.close() - } } initializeClients(collectorIp, collectorTcpPort, config) { diff --git a/lib/client/grpc-readable-stream.js b/lib/client/grpc-readable-stream.js index cdf614a0..32916e57 100644 --- a/lib/client/grpc-readable-stream.js +++ b/lib/client/grpc-readable-stream.js @@ -51,7 +51,7 @@ class GrpcReadableStream { const writableStream = this.makeCall() writableStream.on('error', (error) => { if (error) { - log.error('writable steam error', error) + log.error('writable steam error in GrpcReadableStream', error) } }) @@ -61,6 +61,12 @@ class GrpcReadableStream { end() { this.readableStream.end() + this.writableStream.on('finish', () => { + log.debug('writable stream "finish" event') + }) + this.writableStream.on('close', () => { + log.debug('writable stream "close" event') + }) } } diff --git a/lib/context/disable-trace.js b/lib/context/disable-trace.js index bcc42aa2..fcf6fc39 100644 --- a/lib/context/disable-trace.js +++ b/lib/context/disable-trace.js @@ -11,7 +11,8 @@ const DisableSpanRecorder = require('./disable-span-recorder') // https://github.com/naver/pinpoint/blob/master/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableTrace.java class DisableTrace { - constructor() { + constructor(traceRoot) { + this.traceRoot = traceRoot this.spanRecorder = new DisableSpanRecorder() } diff --git a/lib/context/remote-trace-root-builder.js b/lib/context/remote-trace-root-builder.js new file mode 100644 index 00000000..93c0d652 --- /dev/null +++ b/lib/context/remote-trace-root-builder.js @@ -0,0 +1,43 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +const TraceRootBuilder = require("./trace-root-builder") +const TraceIdBuilder = require("./trace/trace-id-builder") + +class RemoteTraceRoot { + constructor(traceId, traceRoot) { + this.traceId = traceId + this.traceRoot = traceRoot + } + + getTraceStartTime() { + return this.traceRoot.getTraceStartTime() + } +} + +class RemoteTraceRootBuilder { + constructor(agentInfo) { + this.agentInfo = agentInfo + } + + setTraceId(traceId) { + this.traceId = traceId + return this + } + + build(transactionId) { + if (this.traceId) { + return new RemoteTraceRoot(this.traceId, new TraceRootBuilder(this.agentInfo.agentId).build(transactionId)) + } + + const traceId = new TraceIdBuilder(this.agentInfo, transactionId).build() + return new RemoteTraceRoot(traceId, new TraceRootBuilder(this.agentInfo.agentId).build(transactionId)) + } +} + +module.exports = RemoteTraceRootBuilder \ No newline at end of file diff --git a/lib/context/span-builder.js b/lib/context/span-builder.js new file mode 100644 index 00000000..8b7cbb02 --- /dev/null +++ b/lib/context/span-builder.js @@ -0,0 +1,26 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +class Span { + constructor(traceRoot) { + this.traceRoot = traceRoot + this.startTime = traceRoot.getTraceStartTime() + } +} + +class SpanBuilder { + constructor(traceRoot) { + this.traceRoot = traceRoot + } + + build() { + return new Span(this.traceRoot) + } +} + +module.exports = SpanBuilder \ No newline at end of file diff --git a/lib/context/span-chunk-builder.js b/lib/context/span-chunk-builder.js new file mode 100644 index 00000000..308b9d56 --- /dev/null +++ b/lib/context/span-chunk-builder.js @@ -0,0 +1,25 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' +class SpanChunk { + constructor(traceRoot, spanEventList) { + this.traceRoot = traceRoot + this.spanEventList = spanEventList + } +} + +class SpanChunkBuilder { + constructor(traceRoot) { + this.traceRoot = traceRoot + } + + build(spanEventList) { + return new SpanChunk(this.traceRoot, spanEventList) + } +} + +module.exports = SpanChunkBuilder \ No newline at end of file diff --git a/lib/context/span-chunk.js b/lib/context/span-chunk.js index 42879287..5a246745 100644 --- a/lib/context/span-chunk.js +++ b/lib/context/span-chunk.js @@ -29,12 +29,12 @@ class SpanChunk { this.localAsyncId = asyncId } - static getFactoryMethod(agentInfo, traceId) { - return (spanEventList) => new SpanChunk(agentInfo, traceId, null, spanEventList) + static getFactoryMethod(traceId, agentInfo) { + return (spanEventList) => new SpanChunk(traceId, agentInfo, null, spanEventList) } - static getAsyncFactoryMethod(agentInfo, traceId, asyncId) { - return (spanEventList) => new SpanChunk(agentInfo, traceId, asyncId, spanEventList) + static getAsyncFactoryMethod(traceId, agentInfo, asyncId) { + return (spanEventList) => new SpanChunk(traceId, agentInfo, asyncId, spanEventList) } get spanMessage() { diff --git a/lib/context/trace-builder.js b/lib/context/trace-builder.js new file mode 100644 index 00000000..f7c43ace --- /dev/null +++ b/lib/context/trace-builder.js @@ -0,0 +1,32 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +class Trace { + constructor(span, repository, spanRecorder, spanEventRecorder) { + this.span = span + this.repository = repository + this.spanRecorder = spanRecorder + this.spanEventRecorder = spanEventRecorder + } + +} + +class TraceBuilder { + constructor(span, repository, spanRecorder, spanEventRecorder) { + this.span = span + this.repository = repository + this.spanRecorder = spanRecorder + this.spanEventRecorder = spanEventRecorder + } + + build() { + return new Trace(this.span, this.repository, this.spanRecorder, this.spanEventRecorder) + } +} + +module.exports = TraceBuilder \ No newline at end of file diff --git a/lib/context/trace-context.js b/lib/context/trace-context.js index 7132435a..de9b0fa7 100644 --- a/lib/context/trace-context.js +++ b/lib/context/trace-context.js @@ -14,40 +14,28 @@ const log = require('../utils/logger') const sampler = require('../sampler/sampler') const DisableTrace = require('./disable-trace') const localStorage = require('../instrumentation/context/local-storage') +const TraceRootBuilder = require('./trace-root-builder') +const RemoteTraceRootBuilder = require('./remote-trace-root-builder') +const activeRequestRepository = require('./trace/active-request-repository') +const TraceSampler = require('./trace/trace-sampler') +const SpanBuilder = require('./span-builder') +const SpanChunkBuilder = require('./span-chunk-builder') +const SpanRepository = require('./trace/span-repository') +const SpanRecorder = require('./span-recorder') +const SpanEventRecorderBuilder = require('./trace/span-event-recorder-builder') +const TraceBuilder = require('./trace-builder') class TraceContext { - constructor() { - this.agentInfo = null - this.dataSender = null - } - - /** - * trace context singleton instance - * @param {string} options - * @param {string} dataSender - * @param {string} config - * @returns {TraceContext} - * @constructor - */ - static init(options, dataSender, config) { - if (!options.agentId || !options.applicationName) { - throw new Error('Fail to initialize pinpoint context') - } - - const instance = new TraceContext() - instance.agentInfo = { - agentId: options.agentId, - applicationName: options.applicationName, - agentStartTime: options.agentStartTime, - serviceType: options.serviceType, - } - instance.dataSender = dataSender + constructor(agentInfo, dataSender, config) { + this.agentInfo = agentInfo + this.dataSender = dataSender + this.config = config if (config) { - instance.isSampling = sampler.getIsSampling(config.sampling, config.sampleRate) - instance.enableSampling = config.sampling + this.isSampling = sampler.getIsSampling(config.sampling, config.sampleRate) + this.enableSampling = config.sampling } - - return instance + this.traceSampler = new TraceSampler(config) + this.localTraceRootBuilder = new TraceRootBuilder(agentInfo.agentId) } continueTraceObject(requestData) { @@ -120,6 +108,35 @@ class TraceContext { return this.newTraceObject(this.isSampling()) } } + + // disableSampling() method in DefaultBaseTraceFactory.java + disableSampling() { + const state = this.traceSampler.getContinueDisabledState() + return this.newLocalTrace(state.nextId()) + } + + newLocalTrace(nextDisabledId) { + const traceRoot = this.localTraceRootBuilder.build(nextDisabledId) + activeRequestRepository.registry(traceRoot) + return new DisableTrace(traceRoot) + } + + // newTraceObject method in DefaultBaseTraceFactory.java + newTraceObject2(urlPath) { + const state = this.traceSampler.newState(urlPath) + if (!state.isSampled()) { + return this.newLocalTrace(state.nextId()) + } + + const traceRoot = new RemoteTraceRootBuilder(this.agentInfo).build(state.nextId()) + const span = new SpanBuilder(traceRoot).build() + const spanChunkBuilder = new SpanChunkBuilder(traceRoot) + const repository = new SpanRepository(spanChunkBuilder, this.dataSender) + + const spanRecorder = new SpanRecorder(span) + const spanEventRecorder = new SpanEventRecorderBuilder(traceRoot).build() + return new TraceBuilder(span, repository, spanRecorder, spanEventRecorder).build() + } } -module.exports = TraceContext +module.exports = TraceContext \ No newline at end of file diff --git a/lib/context/trace-root-builder.js b/lib/context/trace-root-builder.js new file mode 100644 index 00000000..e6303d8b --- /dev/null +++ b/lib/context/trace-root-builder.js @@ -0,0 +1,31 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +class TraceRoot { + constructor(agentId, traceStartTime, transactionId) { + this.agentId = agentId + this.traceStartTime = traceStartTime + this.transactionId = transactionId + } + + getTraceStartTime() { + return this.traceStartTime + } +} + +class TraceRootBuilder { + constructor(agentId) { + this.agentId = agentId + } + + build(transactionId) { + return new TraceRoot(this.agentId, Date.now(), transactionId) + } +} + +module.exports = TraceRootBuilder \ No newline at end of file diff --git a/lib/context/trace/active-request-repository.js b/lib/context/trace/active-request-repository.js new file mode 100644 index 00000000..a46f295f --- /dev/null +++ b/lib/context/trace/active-request-repository.js @@ -0,0 +1,23 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' +const SimpleCache = require('../../utils/simple-cache') +class ActiveRequestRepository { + constructor() { + this.cache = new SimpleCache() + } + + registry(traceRoot) { + this.cache.put(traceRoot.transactionId, traceRoot) + } + + remove(traceRoot) { + this.cache.delete(traceRoot.transactionId) + } +} + +module.exports = new ActiveRequestRepository() \ No newline at end of file diff --git a/lib/context/trace/continue-disabled-id.js b/lib/context/trace/continue-disabled-id.js new file mode 100644 index 00000000..3f8d9069 --- /dev/null +++ b/lib/context/trace/continue-disabled-id.js @@ -0,0 +1,17 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +const LongIdGenerator = require("./long-id-generator") + +// INITIAL_CONTINUED_DISABLED_ID in AtomicIdGenerator.java +const continueDisabledId = new LongIdGenerator(-1003) +module.exports = { + next: function () { + return continueDisabledId.next(-5) + } +} \ No newline at end of file diff --git a/lib/context/trace/id-generator.js b/lib/context/trace/id-generator.js new file mode 100644 index 00000000..2a0d04d1 --- /dev/null +++ b/lib/context/trace/id-generator.js @@ -0,0 +1,33 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +const LongIdGenerator = require("./long-id-generator") + +// INITIAL_TRANSACTION_ID +const transactionId = new LongIdGenerator(1) +// INITIAL_CONTINUED_TRANSACTION_ID +const continuedTransactionId = new LongIdGenerator(-1001) +// INITIAL_DISABLED_ID in AtomicIdGenerator.java +const disabledId = new LongIdGenerator(-1002) +// INITIAL_CONTINUED_DISABLED_ID in AtomicIdGenerator.java +const continueDisabledId = new LongIdGenerator(-1003) + +module.exports = { + nextTransactionId: function () { + return transactionId.next(1) + }, + nextContinuedTransactionId: function () { + return continuedTransactionId.next(-5) + }, + nextDisabledId: function () { + return disabledId.next(-5) + }, + nextContinuedDisabledId: function () { + return continueDisabledId.next(-5) + } +} \ No newline at end of file diff --git a/lib/context/trace/long-id-generator.js b/lib/context/trace/long-id-generator.js new file mode 100644 index 00000000..2c84c5f1 --- /dev/null +++ b/lib/context/trace/long-id-generator.js @@ -0,0 +1,31 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +// IdGenerator.java +class LongIdGenerator { + constructor(initValue = 0, maxValue = Number.MAX_SAFE_INTEGER) { + this.initValue = initValue + this.maxValue = maxValue + this.sequence = initValue + } + + next(delta = 1) { + if (this.sequence > this.maxValue) { + this.sequence = this.initValue + } + this.sequence = this.sequence + delta + return '' + this.sequence + } + + // for test + reset() { + this.sequence = this.initValue + } +} + +module.exports = LongIdGenerator \ No newline at end of file diff --git a/lib/context/trace/span-event-recorder-builder.js b/lib/context/trace/span-event-recorder-builder.js new file mode 100644 index 00000000..48dac7f5 --- /dev/null +++ b/lib/context/trace/span-event-recorder-builder.js @@ -0,0 +1,25 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +class SpanEventRecorder { + constructor(traceRoot) { + this.traceRoot = traceRoot + } +} + +class SpanEventRecorderBuilder { + constructor(traceRoot) { + this.traceRoot = traceRoot + } + + build() { + return new SpanEventRecorder(this.traceRoot) + } +} + +module.exports = SpanEventRecorderBuilder \ No newline at end of file diff --git a/lib/context/trace/span-repository.js b/lib/context/trace/span-repository.js new file mode 100644 index 00000000..8aeda341 --- /dev/null +++ b/lib/context/trace/span-repository.js @@ -0,0 +1,17 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +// BufferedStorage.java +class SpanRepository { + constructor(spanChunkBuilder, dataSender) { + this.spanChunkBuilder = spanChunkBuilder + this.dataSender = dataSender + } +} + +module.exports = SpanRepository \ No newline at end of file diff --git a/lib/context/trace/trace-id-builder.js b/lib/context/trace/trace-id-builder.js new file mode 100644 index 00000000..b64859a1 --- /dev/null +++ b/lib/context/trace/trace-id-builder.js @@ -0,0 +1,28 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +class TraceId { + constructor(agentId, agentStartTime, transactionId) { + this.agentId = agentId + this.agentStartTime = agentStartTime + this.transactionId = transactionId + } +} + +class TraceIdBuilder { + constructor(agentInfo, transactionId) { + this.agentInfo = agentInfo + this.transactionId = transactionId + } + + build() { + return new TraceId(this.agentInfo.agentId, this.agentInfo.agentStartTime, this.transactionId) + } +} + +module.exports = TraceIdBuilder \ No newline at end of file diff --git a/lib/context/trace/trace-sampler.js b/lib/context/trace/trace-sampler.js new file mode 100644 index 00000000..5d013d66 --- /dev/null +++ b/lib/context/trace/trace-sampler.js @@ -0,0 +1,71 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +const AntPathMatcher = require('../../utils/ant-path-matcher') +const { nextTransactionId, nextContinuedTransactionId, nextDisabledId, nextContinuedDisabledId } = require('./id-generator') + +class TraceSampler { + constructor(config) { + this.config = config + + this.newSuccessState = { + isSampled() { + return true + }, + nextId() { + return nextTransactionId() + } + } + + this.newDisableState = { + isSampled() { + return false + }, + nextId() { + return nextDisabledId() + } + } + + this.continueSuccessState = { + isSampled() { + return true + }, + nextId() { + return nextContinuedTransactionId() + } + } + + this.continueDisableState = { + isSampled() { + return false + }, + nextId() { + return nextContinuedDisabledId() + } + } + + this.pathMatcher = new AntPathMatcher(config) + } + + getContinueSuccessState() { + return this.continueSuccessState + } + + getContinueDisabledState() { + return this.continueDisableState + } + + newState(urlPath) { + if (this.pathMatcher.matchPath(urlPath)) { + return this.newDisableState + } + return this.newSuccessState + } +} + +module.exports = TraceSampler \ No newline at end of file diff --git a/lib/instrumentation/http-shared.js b/lib/instrumentation/http-shared.js index 36245711..fd1dde0a 100644 --- a/lib/instrumentation/http-shared.js +++ b/lib/instrumentation/http-shared.js @@ -17,6 +17,7 @@ const defaultPredefinedMethodDescriptorRegistry = require('../constant/default-p const ServiceType = require('../context/service-type') const localStorage = require('./context/local-storage') const TraceBuilder = require('./context/trace-builder') +const HttpRequestTraceBuilder = require('./http/http-request-trace-builder') let pathMatcher const getPathMatcher = () => { @@ -37,9 +38,7 @@ exports.instrumentRequest = function (agent) { return original.apply(this, arguments) } - if (log.isInfo()) { - log.info('instrumentRequest in http-shared.js ' + JSON.stringify(req)) - } + // const requestTrace = new HttpRequestTraceBuilder(agent.traceContext, req).build() const requestData = RequestHeaderUtils.read(req) if (getPathMatcher().matchPath(requestData.rpcName)) { diff --git a/lib/instrumentation/http/http-request-trace-builder.js b/lib/instrumentation/http/http-request-trace-builder.js new file mode 100644 index 00000000..f0fa2bdc --- /dev/null +++ b/lib/instrumentation/http/http-request-trace-builder.js @@ -0,0 +1,56 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +const TraceHeaderBuilder = require('./trace-header-builder') + +class HttpRequestTrace { + constructor(rpcName, traceFactory) { + this.rpcName = rpcName + this.traceFactory = traceFactory + } + + makeTrace() { + return this.traceFactory() + } +} + +// RequestTraceReader.java +class HttpRequestTraceBuilder { + constructor(traceContext, request) { + this.traceContext = traceContext + this.request = request + } + + build() { + const url = new URL(`http://${process.env.HOST ?? 'localhost'}${this.request.url}`) + const requestTrace = this.makeRequestTrace(url.pathname) + return requestTrace + } + + // read method in java agent + makeRequestTrace(rpcName) { + const traceHeader = new TraceHeaderBuilder(this.request).build() + if (traceHeader.isDisable()) { + return new HttpRequestTrace(rpcName, () => { + return this.traceContext.disableSampling() + }) + } + + if (traceHeader.isNewTrace()) { + return new HttpRequestTrace(rpcName, () => { + return this.traceContext.newTraceObject2() + }) + } + + return new HttpRequestTrace(rpcName, () => { + return this.traceContext.continueTraceObject() + }) + } +} + +module.exports = HttpRequestTraceBuilder \ No newline at end of file diff --git a/lib/instrumentation/http/trace-header-builder.js b/lib/instrumentation/http/trace-header-builder.js new file mode 100644 index 00000000..9d5807dc --- /dev/null +++ b/lib/instrumentation/http/trace-header-builder.js @@ -0,0 +1,87 @@ +/** + * Pinpoint Node.js Agent + * Copyright 2020-present NAVER Corp. + * Apache License v2.0 + */ + +'use strict' + +const samplingFlag = require("../../sampler/sampling-flag") + +class Header { + static sampled = 'Pinpoint-Sampled' + static traceId = 'Pinpoint-TraceID' + static parentSpanId = 'Pinpoint-pSpanID' + static spanId = 'Pinpoint-SpanID' +} + +class TraceHeader { + static newTrace = new TraceHeader() + static disable = new TraceHeader() + + constructor(transactionId, spanId, parentSpanId, flags) { + this.transactionId = transactionId + this.spanId = spanId + this.parentSpanId = parentSpanId + this.flags = flags + } + + isNewTrace() { + return this === TraceHeader.newTrace + } + + isDisable() { + return this === TraceHeader.disable + } +} + +class TraceHeaderBuilder { + constructor(request) { + this.request = request + } + + // DefaultTraceHeaderReader.java + build() { + if (!this.request) { + return TraceHeader.disable + } + + if (typeof this.request.getHeader !== 'function') { + return TraceHeader.disable + } + + const sampled = this.sampled() + if (sampled) { + return TraceHeader.disable + } + + const traceId = this.request.getHeader(Header.traceId) + if (!traceId) { + return TraceHeader.newTrace + } + + const parentSpanId = this.request.getHeader(Header.parentSpanId) + if (!parentSpanId) { + return TraceHeader.newTrace + } + + const spanId = this.request.getHeader(Header.spanId) + if (!spanId) { + return TraceHeader.newTrace + } + + flags = parseInt(this.request.getHeader(Header.flags) || '0') + if (Number.isNaN(flags)) { + flags = 0 + } + + return new TraceHeader(traceId, spanId, parentSpanId, flags) + } + + sampled() { + const sampled = this.request.getHeader(Header.sampled) + return samplingFlag.isSamplingFlag(sampled) + } +} + +module.exports = TraceHeaderBuilder \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 84856aa2..e8eb62f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "mongoose": "^5.4.3", "mysql": "^2.18.1", "mysql2": "^3.6.0", - "nyc": "^15.1.0", + "nyc": "^17.1.0", "redis": "^3.1.2", "rimraf": "^2.6.2", "tape": "^4.16.0", @@ -56,6 +56,7 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -65,12 +66,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/highlight": "^7.25.7", "picocolors": "^1.0.0" }, "engines": { @@ -78,30 +80,32 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz", - "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", + "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", - "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", + "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.9", - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-module-transforms": "^7.24.9", - "@babel/helpers": "^7.24.8", - "@babel/parser": "^7.24.8", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.9", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helpers": "^7.25.7", + "@babel/parser": "^7.25.8", + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.8", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -120,41 +124,45 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.9.tgz", - "integrity": "sha512-G8v3jRg+z8IwY1jHFxvCNhOPYPterE4XljNgdGTYfSTtzzwjIswIzIaSPSLs3R7yFuqnqNeay5rjICfqVr+/6A==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.9", + "@babel/types": "^7.25.7", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz", - "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", + "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.8", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", + "@babel/compat-data": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -167,6 +175,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } @@ -176,71 +185,36 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz", - "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", + "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -250,77 +224,71 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", + "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz", - "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", + "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.8" + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -334,6 +302,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -346,6 +315,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -360,6 +330,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -368,13 +339,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -384,6 +357,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -393,6 +367,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -401,10 +376,14 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", - "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", + "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.8" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -413,33 +392,32 @@ } }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz", - "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.8", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.8", - "@babel/types": "^7.24.8", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -452,18 +430,20 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.24.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz", - "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -721,6 +701,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -735,6 +716,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -744,6 +726,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -752,13 +735,15 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -1357,10 +1342,11 @@ } }, "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "dev": true, + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1480,10 +1466,11 @@ "dev": true }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dev": true, + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -1493,7 +1480,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -1508,6 +1495,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -1516,7 +1504,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -1529,9 +1518,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", - "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "dev": true, "funding": [ { @@ -1547,10 +1536,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001640", - "electron-to-chromium": "^1.4.820", - "node-releases": "^2.0.14", + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.0" }, "bin": { @@ -1696,9 +1686,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001642", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz", - "integrity": "sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==", + "version": "1.0.30001668", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz", + "integrity": "sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==", "dev": true, "funding": [ { @@ -1713,7 +1703,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", @@ -1891,10 +1882,11 @@ "dev": true }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2319,10 +2311,11 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.827", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.827.tgz", - "integrity": "sha512-VY+J0e4SFcNfQy19MEoMdaIcZLmDCprqvBtkii1WTCTQHpRvf5N8+3kTYCgL/PcntvwQvmMJWTuDPsq+IlhWKQ==", - "dev": true + "version": "1.5.38", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.38.tgz", + "integrity": "sha512-VbeVexmZ1IFh+5EfrYz1I0HTzHVIlJa112UEWhciPyeOcKJGeTv6N8WnG4wsQB81DGCaVEGhpSb6o6a8WYFXXg==", + "dev": true, + "license": "ISC" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -2565,9 +2558,10 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -2917,6 +2911,7 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3010,37 +3005,38 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -3060,6 +3056,16 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -3147,13 +3153,14 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -3169,15 +3176,27 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, + "node_modules/finalhandler/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/find-cache-dir": { "version": "3.3.2", @@ -3411,6 +3430,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -4341,27 +4361,20 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" }, "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node": ">=10" } }, "node_modules/istanbul-lib-processinfo": { @@ -4469,7 +4482,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -4484,15 +4498,16 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-buffer": { @@ -4518,6 +4533,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -4687,10 +4703,11 @@ } }, "node_modules/koa-router/node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dev": true, + "license": "MIT", "dependencies": { "isarray": "0.0.1" } @@ -4904,10 +4921,14 @@ "optional": true }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/methods": { "version": "1.1.2", @@ -4923,6 +4944,7 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -5345,10 +5367,11 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -5379,10 +5402,11 @@ } }, "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz", + "integrity": "sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", @@ -5391,12 +5415,12 @@ "decamelize": "^1.2.0", "find-cache-dir": "^3.2.0", "find-up": "^4.1.0", - "foreground-child": "^2.0.0", + "foreground-child": "^3.3.0", "get-package-type": "^0.1.0", "glob": "^7.1.6", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-instrument": "^6.0.2", "istanbul-lib-processinfo": "^2.0.2", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", @@ -5416,7 +5440,7 @@ "nyc": "bin/nyc.js" }, "engines": { - "node": ">=8.9" + "node": ">=18" } }, "node_modules/nyc/node_modules/cliui": { @@ -5443,6 +5467,36 @@ "node": ">=8" } }, + "node_modules/nyc/node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nyc/node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/nyc/node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -5873,16 +5927,18 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", - "dev": true + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "dev": true, + "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true, + "license": "ISC" }, "node_modules/pkg-dir": { "version": "4.2.0", @@ -6101,12 +6157,13 @@ } }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -6146,6 +6203,7 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -6515,10 +6573,11 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -6543,6 +6602,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -6551,13 +6611,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/seq-queue": { "version": "0.0.5", @@ -6566,20 +6628,31 @@ "dev": true }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, + "license": "MIT", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -7179,6 +7252,7 @@ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -7420,9 +7494,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -7438,9 +7512,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -7623,7 +7698,8 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yaml": { "version": "2.4.5", diff --git a/package.json b/package.json index d2072775..ff3f490b 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "mongoose": "^5.4.3", "mysql": "^2.18.1", "mysql2": "^3.6.0", - "nyc": "^15.1.0", + "nyc": "^17.1.0", "redis": "^3.1.2", "rimraf": "^2.6.2", "tape": "^4.16.0", diff --git a/test/client/grpc-data-sender-client-side-stream.test.js b/test/client/grpc-data-sender-client-side-stream.test.js index ac962546..26b16cbc 100644 --- a/test/client/grpc-data-sender-client-side-stream.test.js +++ b/test/client/grpc-data-sender-client-side-stream.test.js @@ -13,7 +13,6 @@ const { log } = require('../test-helper') const GrpcDataSender = require('../../lib/client/grpc-data-sender') const Span = require('../../lib/context/span') const GrpcClientSideStream = require('../../lib/client/grpc-client-side-stream') -var _ = require('lodash') let actuals @@ -289,6 +288,9 @@ test('gRPC client side stream reconnect test', (t) => { function sendSpan1(call, callback) { call.on('data', function () { actualsSpanSession.serverDataCount++ + if (typeof actualsSpanSession.callback === 'function') { + actualsSpanSession.callback(actualsSpanSession.serverDataCount) + } }) call.on('error', function (error) { log.debug(`error: ${error}`) @@ -324,26 +326,17 @@ test('spanStream ERR_STREAM_WRITE_AFTER_END', (t) => { 'starttime': Date.now() }) - let callOrder = 0 - this.grpcDataSender.spanStream.callback = () => { - callOrder++ - process.nextTick(() => { - if (callOrder == 1) { - t.true(true, `actualsSpanSession.serverDataCount: ${actualsSpanSession.serverDataCount}, on('data') count : ${callOrder}, actualsSpanSession.serverEndCount: ${actualsSpanSession.serverEndCount}`) - server.forceShutdown() - t.end() - } - }) + actualsSpanSession.callback = (count) => { + if (count == callCount) { + t.end() + } } - for (let index = 0; index < callCount + 1; index++) { - _.delay(() => { - if (index == callCount - 8) { - this.grpcDataSender.spanStream.grpcStream.end() - } else { - this.grpcDataSender.sendSpan(span) - } - }, _.random(10, 150)) + for (let index = 0; index < callCount; index++) { + if (0 == index % 2) { + this.grpcDataSender.spanStream.grpcStream.end() + } + this.grpcDataSender.sendSpan(span) } this.grpcDataSender.pingStream.grpcStream.end() @@ -372,6 +365,10 @@ test('gRPC stream write retry test', (t) => { } else { callback(new Error('Unknow exception')) } + }, + once: function () { + }, + end: function () { } } }) diff --git a/test/client/grpc-data-sender.test.js b/test/client/grpc-data-sender.test.js index cdde06f2..0572d937 100644 --- a/test/client/grpc-data-sender.test.js +++ b/test/client/grpc-data-sender.test.js @@ -20,13 +20,17 @@ const { Empty } = require('google-protobuf/google/protobuf/empty_pb') const Annotations = require('../../lib/instrumentation/context/annotation/annotations') const CallArgumentsBuilder = require('../../lib/client/call-arguments-builder') -function sendSpan(call, callback) { +let sendSpanMethodOnDataCallback +function sendSpan(call) { call.on('error', function (error) { }) call.on('data', function (spanMessage) { const span = spanMessage.getSpan() const callRequests = getCallRequests() callRequests.push(span) + if (typeof sendSpanMethodOnDataCallback === 'function') { + sendSpanMethodOnDataCallback(span) + } }) call.on('end', function () { }) @@ -47,24 +51,25 @@ class DataSource extends DataSourceCallCountable { initializeProfilerClients() { } } -test('Should send span ', function (t) { +test('Should send span', function (t) { + sendSpanMethodOnDataCallback = null const expectedSpan = { 'traceId': { 'transactionId': { 'agentId': 'express-node-sample-id', - 'agentStartTime': 1592572771026, - 'sequence': 5 + 'agentStartTime': '1592572771026', + 'sequence': '5' }, - 'spanId': 2894367178713953, - 'parentSpanId': -1, + 'spanId': '2894367178713953', + 'parentSpanId': '-1', 'flag': 0 }, 'agentId': 'express-node-sample-id', 'applicationName': 'express-node-sample-name', 'agentStartTime': 1592572771026, 'serviceType': 1400, - 'spanId': 2894367178713953, - 'parentSpanId': -1, + 'spanId': '2894367178713953', + 'parentSpanId': '-1', 'transactionId': { 'type': 'Buffer', 'data': [0, 44, 101, 120, 112, 114, 101, 115, 115, 45, 110, 111, 100, 101, 45, 115, 97, 109, 112, 108, 101, 45, 105, 100, 210, 245, 239, 229, 172, 46, 5] @@ -106,73 +111,68 @@ test('Should send span ', function (t) { let dataSender server.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { dataSender = beforeSpecificOne(port, DataSource) + sendSpanMethodOnDataCallback = (actual) => { + t.true(actual != null, 'spanChunk send') + t.equal(actual.getVersion(), 1, `spanChunk version is ${actual.getVersion()}`) + + const actualTransactionId = actual.getTransactionid() + t.equal(actualTransactionId.getAgentid(), span.agentId, `agentId ${span.agentId}`) + t.equal(actualTransactionId.getAgentstarttime(), span.traceId.transactionId.agentStartTime, 'agent start time') + t.equal(actualTransactionId.getSequence(), span.traceId.transactionId.sequence, `sequence ${span.traceId.transactionId.sequence}`) + t.equal(actual.getSpanid(), span.spanId, 'span ID') + t.equal(actual.getParentspanid(), span.parentSpanId, 'parent span ID') + + t.equal(actual.getStarttime(), span.startTime, 'startTimeStamp') + t.equal(actual.getElapsed(), 28644, 'elapsed time') + t.equal(actual.getApiid(), 1, 'api ID') + + t.equal(actual.getServicetype(), 1400, 'service type') + + const actualAcceptEvent = actual.getAcceptevent() + t.equal(actualAcceptEvent.getRpc(), '/', 'rpc') + t.equal(actualAcceptEvent.getEndpoint(), 'localhost:3000', 'endPoint') + t.equal(actualAcceptEvent.getRemoteaddr(), '::1', 'remoteAddr') + + t.equal(actual.getFlag(), 0, 'flag') + t.equal(actual.getErr(), 1, 'Error') + + const actualSpanEvents = actual.getSpaneventList() + actualSpanEvents.forEach(pSpanEvent => { + t.equal(pSpanEvent.getSequence(), 10, 'sequence') + t.equal(pSpanEvent.getDepth(), 1, 'depth') + + t.equal(pSpanEvent.getStartelapsed(), 72, 'startElapsed') + t.equal(pSpanEvent.getEndelapsed(), 0, 'endElapsed') + + t.equal(pSpanEvent.getServicetype(), 9057, 'serviceType') + + const pAnnotations = pSpanEvent.getAnnotationList() + pAnnotations.forEach(annotation => { + t.equal(annotation.getKey(), 12, 'annotation key') + const pAnnotationValue = annotation.getValue() + t.equal(pAnnotationValue.getStringvalue(), 'http.request', 'annotation string value') + }) + }) + + t.equal(actual.getApiid(), 1, 'API ID') + t.equal(actual.getExceptioninfo(), undefined, 'span exceptionInfo') + + t.equal(actual.getApplicationservicetype(), 1400, 'applicaiton service type') + t.equal(actual.getLoggingtransactioninfo(), 0, 'logging transaction info') + + afterOne(t) + } dataSender.sendSpan(span) - afterOne(t) }) t.teardown(() => { dataSender.close() server.forceShutdown() }) - - const grpcDataSender = new MockGrpcDataSender('', 0, 0, 0, { agentId: 'agent', applicationName: 'applicationName', agentStartTime: 1234344 }) - grpcDataSender.sendSpan(span) - - t.plan(20) - - const actual = grpcDataSender.actualSpan.getSpan() - t.true(actual != null, 'spanChunk send') - t.equal(actual.getVersion(), 1, 'spanChunk version is 1') - - const actualTransactionId = actual.getTransactionid() - t.equal(actualTransactionId.getAgentid(), 'express-node-sample-id', 'gRPC agentId') - t.equal(actualTransactionId.getAgentstarttime(), 1592572771026, 'agent start time') - t.equal(actualTransactionId.getSequence(), 5) - - t.equal(actual.getSpanid(), 2894367178713953, 'span ID') - t.equal(actual.getParentspanid(), -1, 'parent span ID') - - t.equal(actual.getStarttime(), 1592574173350, 'startTimeStamp') - t.equal(actual.getElapsed(), 28644, 'elapsed time') - t.equal(actual.getApiid(), 1, 'api ID') - - t.equal(actual.getServicetype(), 1400, 'service type') - - const actualAcceptEvent = actual.getAcceptevent() - t.equal(actualAcceptEvent.getRpc(), '/', 'rpc') - t.equal(actualAcceptEvent.getEndpoint(), 'localhost:3000', 'endPoint') - t.equal(actualAcceptEvent.getRemoteaddr(), '::1', 'remoteAddr') - - t.equal(actual.getFlag(), 0, 'flag') - t.equal(actual.getErr(), 1, 'Error') - - const actualSpanEvents = actual.getSpaneventList() - actualSpanEvents.forEach(pSpanEvent => { - t.equal(pSpanEvent.getSequence(), 10, 'sequence') - t.equal(pSpanEvent.getDepth(), 1, 'depth') - - t.equal(pSpanEvent.getStartelapsed(), 72, 'startElapsed') - t.equal(pSpanEvent.getEndelapsed(), 0, 'endElapsed') - - t.equal(pSpanEvent.getServicetype(), 9057, 'serviceType') - - const pAnnotations = pSpanEvent.getAnnotationList() - pAnnotations.forEach(annotation => { - t.equal(annotation.getKey(), 12, 'annotation key') - const pAnnotationValue = annotation.getValue() - t.equal(pAnnotationValue.getStringvalue(), 'http.request', 'annotation string value') - }) - }) - - t.equal(actual.getApiid(), 1, 'API ID') - t.equal(actual.getExceptioninfo(), null, 'span exceptionInfo') - - t.equal(actual.getApplicationservicetype(), 1400, 'applicaiton service type') - t.equal(actual.getLoggingtransactioninfo(), 0, 'logging transaction info') }) const grpcDataSender = new MockGrpcDataSender('', 0, 0, 0, { agentId: 'agent', applicationName: 'applicationName', agentStartTime: 1234344 }) -test.skip('sendSpanChunk redis.SET.end', function (t) { +test('sendSpanChunk redis.SET.end', function (t) { let expectedSpanChunk = { 'agentId': 'express-node-sample-id', 'applicationName': 'express-node-sample-name', @@ -784,8 +784,8 @@ let handleCommandCall const serverCallWriter = (commandType) => { const result = new cmdMessage.PCmdRequest() result.setRequestid(requestId) - - if (commandType === CommandType.activeThreadCount) { + + if (commandType === CommandType.activeThreadCount) { const commandActiveThreadCount = new cmdMessage.PCmdActiveThreadCount() result.setCommandactivethreadcount(commandActiveThreadCount) } else { @@ -793,7 +793,7 @@ const serverCallWriter = (commandType) => { message.setMessage('echo') result.setCommandecho(message) } - + handleCommandCall.write(result) } @@ -835,7 +835,6 @@ class ProfilerDataSource extends DataSourceCallCountable { } test('sendSupportedServicesCommand and commandEcho', (t) => { - t.plan(4) dataCallbackOnServerCall = null const server = new grpc.Server() server.addService(services.ProfilerCommandServiceService, { @@ -844,7 +843,7 @@ test('sendSupportedServicesCommand and commandEcho', (t) => { }) let dataSender - server.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { + server.bindAsync('127.0.0.1:0', grpc.ServerCredentials.createInsecure(), (error, port) => { dataSender = beforeSpecificOne(port, ProfilerDataSource) const callArguments = new CallArgumentsBuilder(function (error, response) { @@ -856,15 +855,14 @@ test('sendSupportedServicesCommand and commandEcho', (t) => { const cmdEchoResponse = callRequests[1] t.equal(cmdEchoResponse.getMessage(), 'echo', 'echo message') - afterOne(t) + dataSender.commandStream.writableStream.on('close', () => { + t.end() + }) + dataSender.close() + server.forceShutdown() }).build() dataSender.sendSupportedServicesCommand(callArguments) }) - - t.teardown(() => { - dataSender.close() - server.forceShutdown() - }) }) test('CommandStreamActiveThreadCount', (t) => { @@ -875,7 +873,7 @@ test('CommandStreamActiveThreadCount', (t) => { commandStreamActiveThreadCount: emptyResponseService }) let dataSender - server.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { + server.bindAsync('127.0.0.1:0', grpc.ServerCredentials.createInsecure(), (error, port) => { dataSender = beforeSpecificOne(port, ProfilerDataSource) let callCount = 0 @@ -889,19 +887,26 @@ test('CommandStreamActiveThreadCount', (t) => { t.equal(data.getHistogramschematype(), 2, 'histogram schema type') t.equal(data.getActivethreadcountList()[0], 1, 'active thread count') - if (callCount == 2) { - afterOne(t) + console.log(`dataCallbackOnServerCall callCount: ${callCount}`) + if (callCount == 1) { + dataSender.commandStream.writableStream.on('close', () => { + t.end() + }) + dataSender.close() + server.forceShutdown() } } - const callArguments = new CallArgumentsBuilder(function (error, response) { - serverCallWriter(CommandType.activeThreadCount) - serverCallWriter(CommandType.activeThreadCount) + const callArguments = new CallArgumentsBuilder(function () { + if (callArguments.once) { + return + } + callArguments.once = true + + process.nextTick(() => { + serverCallWriter(CommandType.activeThreadCount) + }) }).build() dataSender.sendSupportedServicesCommand(callArguments) }) - t.teardown(() => { - dataSender.close() - server.forceShutdown() - }) }) diff --git a/test/client/grpc-fixture.js b/test/client/grpc-fixture.js index 62d1e407..9b1d8329 100644 --- a/test/client/grpc-fixture.js +++ b/test/client/grpc-fixture.js @@ -23,7 +23,7 @@ function beforeSpecificOne(port, one, serviceConfig) { callRequests = [] callMetadata = [] const actualConfig = config.getConfig({ 'grpc.service_config': serviceConfig }) - actualConfig.collectorIp = 'localhost' + actualConfig.collectorIp = '127.0.0.1' actualConfig.collectorTcpPort = port actualConfig.collectorStatPort = port actualConfig.collectorSpanPort = port diff --git a/test/context/trace-context.test.js b/test/context/trace-context.test.js index 540ec86f..73570780 100644 --- a/test/context/trace-context.test.js +++ b/test/context/trace-context.test.js @@ -20,7 +20,7 @@ test('Should create continued trace and add span info', function (t) { const transactionId = fixture.getTransactionId() const traceId = fixture.getTraceId(transactionId) traceId.sampled = true - const traceContext = TraceContext.init(fixture.getAgentInfo(), dataSenderMock()) + const traceContext = new TraceContext(fixture.getAgentInfo(), dataSenderMock()) const trace = traceContext.continueTraceObject(traceId) localStorage.run(trace, () => { @@ -38,7 +38,7 @@ test('Should begin/end trace block asynchronously', async function (t) { t.plan(4) // start trace and write span info - const traceContext = TraceContext.init(fixture.getAgentInfo(), dataSenderMock()) + const traceContext = new TraceContext(fixture.getAgentInfo(), dataSenderMock()) const startedTrace = traceContext.newTraceObject(true) localStorage.run(startedTrace, () => { @@ -70,7 +70,7 @@ test('Should complete trace ', async function (t) { const transactionId = fixture.getTransactionId() const traceId = fixture.getTraceId(transactionId) - const traceContext = TraceContext.init(fixture.getAgentInfo(), dataSenderMock()) + const traceContext = new TraceContext(fixture.getAgentInfo(), dataSenderMock()) const trace = traceContext.newTraceObject(traceId) @@ -83,7 +83,7 @@ test('Should complete trace ', async function (t) { test('new Trace', (t) => { t.plan(4) - const dut = TraceContext.init(fixture.getAgentInfo(), dataSenderMock(), fixture.config) + const dut = new TraceContext(fixture.getAgentInfo(), dataSenderMock(), fixture.config) t.true(dut.isSampling != null, 'dut is not null') const req = { @@ -104,7 +104,7 @@ test('new Trace', (t) => { test('continue trace', (t) => { t.plan(3) - const dut = TraceContext.init(fixture.getAgentInfo(), dataSenderMock(), fixture.config) + const dut = new TraceContext(fixture.getAgentInfo(), dataSenderMock(), fixture.config) const req = { url: "http://test.com", headers: { diff --git a/test/support/agent-singleton-mock.js b/test/support/agent-singleton-mock.js index 79238dae..74f14be9 100644 --- a/test/support/agent-singleton-mock.js +++ b/test/support/agent-singleton-mock.js @@ -6,14 +6,14 @@ 'use strict' -const { fixture, log } = require('../test-helper') +const { log } = require('../test-helper') const enableDataSending = require('../test-helper').enableDataSending enableDataSending() const Agent = require('../../lib/agent') const dataSenderMock = require('./data-sender-mock') const shimmer = require('@pinpoint-apm/shimmer') const httpShared = require('../../lib/instrumentation/http-shared') -const traceContext = require('../../lib/context/trace-context') +const TraceContext = require('../../lib/context/trace-context') const activeTrace = require('../../lib/metric/active-trace') const apiMetaService = require('../../lib/context/api-meta-service') const { setDataSender } = require('../../lib/client/data-sender-factory') @@ -73,7 +73,7 @@ class MockAgent extends Agent { this.dataSender = dataSenderMock() setDataSender(this.dataSender) - this.traceContext = traceContext.init(this.agentInfo, this.dataSender, this.config) + this.traceContext = new TraceContext(this.agentInfo, this.dataSender, this.config) this.closedTraces = [] } diff --git a/test/utils/ant-path-matcher.test.js b/test/utils/ant-path-matcher.test.js index c98ee45d..4506bad4 100644 --- a/test/utils/ant-path-matcher.test.js +++ b/test/utils/ant-path-matcher.test.js @@ -192,7 +192,7 @@ const TEST_ENV = { const getServerUrl = (path) => `http://${TEST_ENV.host}:${TEST_ENV.port}${path}` async function outgoingRequest(t, path, expectedSampling, expectUnits) { - return new Promise((resolve, reject) => { + return new Promise((resolve) => { const PATH = path const app = new express()