Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Remove last dependencies on SDK package, improve version detection #461

Open
wants to merge 6 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/rollup-config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import typescript from "@rollup/plugin-typescript"
import globby from "globby"
import nodeExternals from "rollup-plugin-node-externals"

const FORMATS = ["es"]
const FORMATS = ["es", "cjs"]

async function task(src, dist, format, sources) {
const dir = path.join(dist, format)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ const linted = await new ESLint({ fix: true }).lintText(formatted, {
})

await fs.writeFile("src/version.ts", linted[0].output)

await fs.mkdir("dist/commonjs", { recursive: true })
await fs.cp("src/commonjs/package.json", "dist/commonjs/package.json")
18 changes: 7 additions & 11 deletions packages/solarwinds-apm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@
"type": "module",
"exports": {
".": {
"import": "./dist/es/index.es.js"
},
"./loader": {
"import": "./dist/es/hooks.es.js"
"import": "./dist/index.js",
"require": "./dist/commonjs/index.js"
}
},
"main": "./dist/cjs/index.cjs.js",
"main": "./dist/commonjs/index.js",
"files": [
"./src/",
"./dist/",
Expand All @@ -50,9 +48,9 @@
"provenance": true
},
"scripts": {
"build": "node version.js && rollup -c --forceExit",
"lint": "node version.js && prettier --check . && eslint . --max-warnings=0",
"lint:fix": "node version.js && eslint --fix . && prettier --write .",
"build": "node build.js && tsc",
"lint": "node build.js && prettier --check . && eslint . --max-warnings=0",
"lint:fix": "node build.js && eslint --fix . && prettier --write .",
"release": "node ../../scripts/publish.js",
"test": "swtest -p test/tsconfig.json -c src"
},
Expand All @@ -74,13 +72,11 @@
"@solarwinds-apm/dependencies": "workspace:^",
"@solarwinds-apm/histogram": "workspace:^",
"@solarwinds-apm/instrumentations": "workspace:^",
"@solarwinds-apm/lazy": "workspace:^",
"@solarwinds-apm/module": "workspace:^",
"@solarwinds-apm/proto": "workspace:^",
"@solarwinds-apm/sampling": "workspace:^",
"@solarwinds-apm/sdk": "workspace:^",
"json-stringify-safe": "^5.0.1",
"semver": "^7.5.4",
"node-releases": "^2.0.18",
"zod": "^3.22.4"
},
"peerDependencies": {
Expand Down
21 changes: 13 additions & 8 deletions packages/solarwinds-apm/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,20 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { context } from "@opentelemetry/api"
import * as sdk from "@solarwinds-apm/sdk"
import { api } from "./init.js"

export function setTransactionName(name: string): boolean {
return sdk.setTransactionName(context.active(), name)
}
export function waitUntilReady(timeout: number): number {
return sdk.waitUntilReady(timeout)
/**
* Wait until the library is ready to sample traces
*
* Note that when exporting to AppOptics this function will block the event loop.
*
* @param timeout - Wait timeout in milliseconds
* @returns Whether the library is ready
*/
export async function waitUntilReady(timeout: number): Promise<boolean> {
return api.waitUntilReady(timeout)
}

export { type Config } from "./config.js"
export { FULL_VERSION, VERSION } from "./version.js"
export { setTransactionName } from "./processing/transaction-name.js"
export { VERSION } from "./version.js"
16 changes: 8 additions & 8 deletions packages/solarwinds-apm/src/appoptics/exporters/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

import util from "node:util"

import { type Attributes, type DiagLogger } from "@opentelemetry/api"
import { type Attributes } from "@opentelemetry/api"
import {
type ExportResult,
ExportResultCode,
Expand All @@ -40,15 +40,15 @@ import {
type Histogram,
} from "@solarwinds-apm/histogram"

import { componentLogger } from "../../logger.js"

const MAX_TAGS = 50

export class AppopticsMetricExporter {
readonly #logger = componentLogger(AppopticsMetricExporter)
readonly #reporter: oboe.Reporter

constructor(
reporter: oboe.Reporter,
protected readonly logger: DiagLogger,
) {
constructor(reporter: oboe.Reporter) {
this.#reporter = reporter
}

Expand Down Expand Up @@ -100,7 +100,7 @@ export class AppopticsMetricExporter {
tagCount,
)
} else {
this.logger.warn(
this.#logger.warn(
"gauges with delta aggregation are not supported",
)
}
Expand All @@ -113,7 +113,7 @@ export class AppopticsMetricExporter {
)
this.#exportHistogram(histogram, name, tags, tagCount)
} else {
this.logger.warn(
this.#logger.warn(
"histograms with cumulative aggregation are not supported",
)
}
Expand All @@ -126,7 +126,7 @@ export class AppopticsMetricExporter {
)
this.#exportHistogram(histogram, name, tags, tagCount)
} else {
this.logger.warn(
this.#logger.warn(
"histograms with cumulative aggregation are not supported",
)
}
Expand Down
12 changes: 5 additions & 7 deletions packages/solarwinds-apm/src/appoptics/exporters/traces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { inspect } from "node:util"

import {
type AttributeValue,
type DiagLogger,
type SpanContext,
SpanKind,
SpanStatusCode,
Expand All @@ -40,17 +39,16 @@ import {
} from "@opentelemetry/semantic-conventions"
import { oboe } from "@solarwinds-apm/bindings"

import { componentLogger } from "../../logger.js"
import { TRANSACTION_NAME_ATTRIBUTE } from "../../processing/transaction-name.js"
import { traceParent } from "../sampler.js"

export class AppopticsTraceExporter implements SpanExporter {
readonly #logger = componentLogger(AppopticsTraceExporter)
readonly #reporter: oboe.Reporter
#error: Error | undefined = undefined

constructor(
reporter: oboe.Reporter,
protected readonly logger: DiagLogger,
) {
constructor(reporter: oboe.Reporter) {
this.#reporter = reporter
}

Expand Down Expand Up @@ -195,8 +193,8 @@ export class AppopticsTraceExporter implements SpanExporter {
this.#error = new Error(
`Reporter::sendReport returned with error status ${status}`,
)
this.logger.warn("error sending report", this.#error)
this.logger.debug(evt.metadataString())
this.#logger.warn("error sending report", this.#error)
this.#logger.debug(evt.metadataString())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { type DiagLogger, SpanStatusCode } from "@opentelemetry/api"
import { SpanStatusCode } from "@opentelemetry/api"
import { hrTimeToMicroseconds } from "@opentelemetry/core"
import {
NoopSpanProcessor,
type ReadableSpan,
type SpanProcessor,
} from "@opentelemetry/sdk-trace-base"
import { oboe } from "@solarwinds-apm/bindings"
import { type SwConfiguration } from "@solarwinds-apm/sdk"

import { type Configuration } from "../../config.js"
import { componentLogger } from "../../logger.js"
import { isRootOrEntry } from "../../processing/parent-span.js"
import {
computedTransactionName,
Expand All @@ -35,12 +36,10 @@ export class AppopticsInboundMetricsProcessor
extends NoopSpanProcessor
implements SpanProcessor
{
readonly #logger = componentLogger(AppopticsInboundMetricsProcessor)
readonly #defaultTransactionName?: string

constructor(
config: SwConfiguration,
protected readonly logger: DiagLogger,
) {
constructor(config: Configuration) {
super()
this.#defaultTransactionName = config.transactionName
}
Expand All @@ -55,7 +54,7 @@ export class AppopticsInboundMetricsProcessor
const duration = hrTimeToMicroseconds(span.duration)

let transaction = span.attributes[TRANSACTION_NAME_ATTRIBUTE]
this.logger.debug("initial transaction name", transaction)
this.#logger.debug("initial transaction name", transaction)
if (typeof transaction !== "string") {
transaction =
this.#defaultTransactionName ?? computedTransactionName(span)
Expand All @@ -79,7 +78,7 @@ export class AppopticsInboundMetricsProcessor
domain: null,
})
}
this.logger.debug("final transaction name", transaction)
this.#logger.debug("final transaction name", transaction)

span.attributes[TRANSACTION_NAME_ATTRIBUTE] = transaction
}
Expand Down
20 changes: 11 additions & 9 deletions packages/solarwinds-apm/src/appoptics/reporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,29 @@ import {
ATTR_PROCESS_COMMAND_LINE,
} from "@opentelemetry/semantic-conventions/incubating"
import { oboe } from "@solarwinds-apm/bindings"
import { type SwConfiguration } from "@solarwinds-apm/sdk"

import { type Configuration } from "../config.js"
import { modules } from "../metadata.js"
import { VERSION } from "../version.js"
import certificate from "./certificate.js"

export const ERROR: Error | undefined = oboe instanceof Error ? oboe : undefined

export async function reporter(
config: SwConfiguration,
config: Configuration,
resource: Resource,
): Promise<oboe.Reporter> {
const reporter = new oboe.Reporter({
service_key: `${config.token}:${config.serviceName}`,
host: config.collector ?? "",
certificates: config.certificate ?? certificate,
service_key: `${config.serviceKey?.token}:${config.service}`,
host: config.collector,
certificates: config.trustedpath ?? certificate,
grpc_proxy: config.proxy ?? "",
reporter: "ssl",
metric_format: 1,
trace_metrics: 1,

log_level: otelLevelToOboeLevel(config.otelLogLevel),
log_type: otelLevelToOboeType(config.otelLogLevel),
log_level: otelLevelToOboeLevel(config.logLevel),
log_type: otelLevelToOboeType(config.logLevel),
log_file_path: "",

buffer_size: oboe.SETTINGS_UNSET,
Expand All @@ -66,7 +68,7 @@ export async function reporter(
})

const logger = diag.createComponentLogger({
namespace: `[sw/oboe]`,
namespace: `[solarwinds-apm / oboe]`,
})
oboe.debug_log_add((level, sourceName, sourceLine, message) => {
const log = oboeLevelToOtelLogger(level, logger)
Expand All @@ -79,7 +81,7 @@ export async function reporter(
} else {
log(message)
}
}, config.oboeLogLevel)
}, otelLevelToOboeLevel(config.logLevel))

// Send init message
const md = oboe.Metadata.makeRandom(true)
Expand Down
6 changes: 5 additions & 1 deletion packages/solarwinds-apm/src/appoptics/sampler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ export class AppopticsSampler extends Sampler {
}

override toString(): string {
return `Legacy Sampler`
return "AppOptics Sampler"
}

isReady(timeout: number): boolean {
return oboe.Context.isReady(timeout) === oboe.SERVER_RESPONSE_OK
}
}

Expand Down
4 changes: 4 additions & 0 deletions packages/solarwinds-apm/src/commonjs/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"semi": true,
"trailingComma": "none"
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,5 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import config from "@solarwinds-apm/rollup-config"

export default config()
import * as api from "../api.js";
export = api;
37 changes: 37 additions & 0 deletions packages/solarwinds-apm/src/commonjs/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"use strict";

/*
Copyright 2023-2024 SolarWinds Worldwide, LLC.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

module.exports.setTransactionName = function setTransactionName(name) {
if (api) {
return api.setTransactionName(name);
} else {
return false;
}
};

module.exports.waitUntilReady = function waitUntilReady(timeout) {
return imported.then((api) => api.waitUntilReady(timeout));
};

/** @type{import("../api")} */
let api = undefined;
const imported = import("../api.js").then((imported) => {
module.exports.VERSION = imported.VERSION;
api = imported;
return imported;
});
18 changes: 18 additions & 0 deletions packages/solarwinds-apm/src/commonjs/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
Copyright 2023-2024 SolarWinds Worldwide, LLC.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import api from "./api";
export = api;
15 changes: 15 additions & 0 deletions packages/solarwinds-apm/src/commonjs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* eslint-disable */
"use strict";

if (require("./version")) {
if ((!Symbol.for("solarwinds-apm / init")) in global) {
// this will not trigger if customers use the --import flag then use require,
// it will only trigger if they only ever use require
console.warn(
"This library (solarwinds-apm) no longer supports loading via require. " +
"The application may not be instrumented."
);
}

module.exports = require("./api");
}
3 changes: 3 additions & 0 deletions packages/solarwinds-apm/src/commonjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
Loading
Loading