
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@mwcp/otel
Advanced tools
Open Telemetry Component for Midway.js
ESM build only, requires @midwayjs >= 3.16 and set "type": "module" in packages.json
npm i @mwcp/otel
Update project src/configuration.ts
import { Configuration } from '@midwayjs/decorator'
import * as koa from '@midwayjs/koa'
import * as otel from '@mwcp/otel'
@Configuration({
imports: [
koa,
otel,
],
importConfigs: [join(__dirname, 'config')],
})
export class ContainerConfiguration implements ILifeCycle {
}
To try out the OTLPTraceExporter quickly, you can run Jaeger in a docker container:
docker run -d --name jaeger \
-e COLLECTOR_OTLP_ENABLED=true \
-p 4317:4317 \
-p 4318:4318 \
-p 5778:5778 \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 16686:16686 \
jaegertracing/all-in-one:latest
Start project:
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
npm start
Jaeger Web UI address:
Trace Decoratorimport { Trace } from '@mwcp/otel'
@Controller('/')
export class FooController {
@Inject() readonly svc: FooService
/* span name will be `{class name}/{method name}` => "FooController/hello" */
@Trace()
async hello(): Promise<string> {
return 'hello'
}
/* span name will be "hello" */
@Trace('hello')
async world(): Promise<string> {
return 'world'
}
@Trace({
spanName: 'hello'
})
async world2(): Promise<string> {
return 'world'
}
}
Pass scope to avoid the confusion of call chain relationship when async methods are called concurrently
import { Trace } from '@mwcp/otel'
@Controller('/')
export class FooController {
@Trace()
async hello(): Promise<string> {
await Promise.all([
this._simple1(),
this._simple2(),
])
return 'OK'
}
@Trace({ scope: 'hello1' })
async _hello1(): Promise<string> {
return 'world'
}
@Trace({ scope: 'hello2' })
async _hello2(): Promise<string> {
return 'world'
}
@Trace({ scope: 'hello1' })
async _hello1a(): Promise<string> {
return 'world'
}
@Trace({ scope: 'hello2' })
async _hello2a(): Promise<string> {
return 'world'
}
}

Use this inner before() after() point to the decorated instance
export class FooService {
foo = 1
@Trace<Foo['home']>({
before([options], decoratorContext) {
assert(this instanceof FooService) // <--- this point to FooService
assert(this === decoratorContext.instance)
assert(this.foo === 1)
return void 0
},
after([options], res, decoratorContext) {
assert(this instanceof FooService)
assert(this === decoratorContext.instance)
assert(this.foo === 1)
return void 0
},
})
async home(this: FooService, options: InputOptions): Promise<string> { // <--- pass this type explicitly
const ret = await options.input
return ret
}
}
TraceLog DecoratorAdd trace attribute to the span through decorator before()/after() method return object, no new span starting
Note return value of decorated method before() and after() should be type:
interface DecoratorTraceData {
attrs?: Attributes
events?: Attributes
rootAttrs?: Attributes
rootEvents?: Attributes
}
import { TraceLog, DecoratorTraceData } from '@mwcp/otel'
@Controller('/')
export class FooController {
@Trace()
async hello(): Promise<string> {
return 'hello'
}
@TraceLog({
before: async ([input], { instanceName, methodName }) => {
const attrs: Attributes = {
args0: input,
}
const events: Attributes = {
...attrs,
instanceName,
methodName,
}
const rootAttrs: Attributes = { rootAttrs: 'rootAttrs' }
const rootEvents: Attributes = { ...rootAttrs }
return { attrs, events, rootAttrs, rootEvents } as DecoratorTraceData
},
after: ([input], res, { instanceName, methodName }) => {
const attrs: Attributes = {
args0: input,
res,
}
const events: Attributes = {
...attrs,
instanceName,
methodName,
}
return { events }
},
})
async world(): Promise<string> {
return 'world'
}
}
TraceInit Decorator// src/configuration.ts
import { TraceInit } from '@mwcp/otel'
export class AutoConfiguration implements ILifeCycle {
@TraceInit({ namespace: 'Foo' })
async onReady(container: IMidwayContainer): Promise<void> {
// some code
}
}
@Controller('/')
export class FooController {
@Inject() readonly svc: FooService
hello(): string {
// spanName should be 'foo-124-abc'
const msg = this.svc.concat(123, 'abc')
return msg
}
}
@Provide()
export class FooService {
@Trace<FooService['concat']>({
spanName: ([v1, v2]) => `foo-${v1 + 1}-${v2}`,
})
concat(v1: number, v2: string): string {
return `${v1.toString()}-${v2}`
}
@Trace<FooService['concat2']>({
spanName: (args) => `foo-${args[0] + 1}-${args[1]}`,
})
concat2(v1: number, v2: string): string {
return `${v1.toString()}-${v2}`
}
}
FAQs
midway component for open telemetry
The npm package @mwcp/otel receives a total of 173 weekly downloads. As such, @mwcp/otel popularity was classified as not popular.
We found that @mwcp/otel demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.