@evenicanpm/common-core 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evenicanpm/common-core",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Common module for Headless Storefront and Admin panel",
5
5
  "author": "Evenica",
6
6
  "type": "module",
@@ -10,10 +10,21 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@azure/identity": "^4.10.1",
13
- "@azure/keyvault-secrets": "^4.10.0"
13
+ "@azure/keyvault-secrets": "^4.10.0",
14
+ "@azure/monitor-opentelemetry-exporter": "^1.0.0-beta.32",
15
+ "@opentelemetry/api": "^1.9.0",
16
+ "@opentelemetry/api-logs": "^0.206.0",
17
+ "@opentelemetry/exporter-trace-otlp-http": "^0.206.0",
18
+ "@opentelemetry/host-metrics": "^0.36.2",
19
+ "@opentelemetry/sdk-logs": "^0.206.0",
20
+ "@opentelemetry/sdk-metrics": "^2.1.0",
21
+ "@opentelemetry/sdk-trace-node": "^2.1.0",
22
+ "@strapi/client": "^1.5.0",
23
+ "@vercel/otel": "^2.0.1",
24
+ "strapi-sdk-js": "^3.0.0"
14
25
  },
15
26
  "devDependencies": {
16
27
  "@types/node": "^24.0.13"
17
28
  },
18
- "gitHead": "6a95e9f84f48a7e1e96bfdf4ee1a766a7d8808b6"
29
+ "gitHead": "074f33378006dfc21ceb49456806a18dbb6e91ad"
19
30
  }
@@ -0,0 +1 @@
1
+ export * from "./keyvault";
@@ -7,7 +7,7 @@ const vaultEndpoint = process.env.KEYVAULT_ENDPOINT;
7
7
  const url = `https://${vaultName}.${vaultEndpoint}`;
8
8
 
9
9
  // Initialize local secrets cache object
10
- let secrets = new Map();
10
+ const secrets = new Map();
11
11
 
12
12
  // A Key and Secret class to Cache Secrets
13
13
  class Secret {
@@ -27,11 +27,11 @@ class Secret {
27
27
  * set all secrets in the "secrets" map binding which is exported from this module.
28
28
  */
29
29
  const initializeKeyVaultCache = async () => {
30
- if (process.env.NODE_ENV == "production") {
30
+ if (process.env.NODE_ENV === "production") {
31
31
  const credential = new DefaultAzureCredential();
32
32
  const client = new SecretClient(url, credential);
33
33
 
34
- for await (let secretProperties of client.listPropertiesOfSecrets()) {
34
+ for await (const secretProperties of client.listPropertiesOfSecrets()) {
35
35
  const result = await client.getSecret(secretProperties.name);
36
36
  secrets.set(
37
37
  secretProperties.name,
@@ -48,7 +48,7 @@ const initializeKeyVaultCache = async () => {
48
48
  * @returns Returns the secret string.
49
49
  */
50
50
  const getSecret = (key: string): string | undefined => {
51
- if (process.env.NODE_ENV != "production") {
51
+ if (process.env.NODE_ENV !== "production") {
52
52
  const fixedName = key.replace(/-/g, "_");
53
53
  return process.env[fixedName];
54
54
  } else {
@@ -0,0 +1,44 @@
1
+ # Using Opentelemetry in e4
2
+
3
+ - `setup.ts` has two main paths:
4
+ 1. Azure Not Enabled - Will setup OLTP and @vercel/otel Registration for auto instrumentation with nextjs
5
+ 2. Azure Enabled - Does the above AND Azure monitoring for metrics, logs, and traces
6
+
7
+ ## Using a Tracer Example
8
+
9
+ From https://opentelemetry.io/docs/languages/js/instrumentation/
10
+
11
+ ```ts
12
+ import opentelemetry from "@opentelemetry/api";
13
+ //...
14
+
15
+ const tracer = opentelemetry.trace.getTracer(
16
+ "instrumentation-scope-name",
17
+ "instrumentation-scope-version",
18
+ );
19
+
20
+ // You can now use a 'tracer' to do tracing!
21
+ ```
22
+
23
+ ## Starting a Span
24
+
25
+ ```ts
26
+ return tracer.startActiveSpan("rollTheDice", (span: Span) => {
27
+ const result: number[] = [];
28
+ for (let i = 0; i < rolls; i++) {
29
+ result.push(rollOnce(min, max));
30
+ }
31
+ // Be sure to end the span!
32
+ span.end();
33
+ return result;
34
+ });
35
+ ```
36
+
37
+ ## Using the Logger
38
+
39
+ ```ts
40
+ import log from "@evenicanpm/common-core/src/otel/logger";
41
+
42
+ const logger = log();
43
+ logger.info("This is some e4 info!");
44
+ ```
@@ -0,0 +1,54 @@
1
+ import { logs, SeverityNumber } from "@opentelemetry/api-logs";
2
+
3
+ type LogAttriutes = Record<string, string | number | boolean | undefined>;
4
+
5
+ /**
6
+ *
7
+ * Centralized logging using opentelemetry log emitter function.
8
+ *
9
+ */
10
+ function logger() {
11
+ // Global logger is set in ./setup.ts
12
+ const log = logs.getLogger("storefront");
13
+ return {
14
+ info: (message: string, attributes?: LogAttriutes) => {
15
+ log.emit({
16
+ severityNumber: SeverityNumber.INFO,
17
+ body: message,
18
+ attributes,
19
+ });
20
+ },
21
+ debug: (message: string) => {
22
+ log.emit({
23
+ severityNumber: SeverityNumber.DEBUG,
24
+ body: message,
25
+ });
26
+ },
27
+ error: (message: string, error?: unknown, attributes?: LogAttriutes) => {
28
+ const err =
29
+ error instanceof Error
30
+ ? {
31
+ name: error.name,
32
+ message: error.message,
33
+ stack: error.stack,
34
+ }
35
+ : undefined;
36
+ log.emit({
37
+ severityNumber: SeverityNumber.ERROR,
38
+ body: message,
39
+ attributes: {
40
+ ...attributes,
41
+ ...(err && { error: err }),
42
+ },
43
+ });
44
+ },
45
+ warn: (message: string) => {
46
+ log.emit({
47
+ severityNumber: SeverityNumber.WARN,
48
+ body: message,
49
+ });
50
+ },
51
+ };
52
+ }
53
+
54
+ export default logger;
@@ -0,0 +1,99 @@
1
+ import { metrics } from "@opentelemetry/api";
2
+ import { logs } from "@opentelemetry/api-logs";
3
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
4
+ import {
5
+ BatchLogRecordProcessor,
6
+ LoggerProvider,
7
+ } from "@opentelemetry/sdk-logs";
8
+ import {
9
+ MeterProvider,
10
+ PeriodicExportingMetricReader,
11
+ } from "@opentelemetry/sdk-metrics";
12
+ import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-node";
13
+ import { registerOTel } from "@vercel/otel";
14
+
15
+ /**
16
+ * The configuration object passed to setupOtel function.
17
+ */
18
+ interface otelConfig {
19
+ serviceName: string;
20
+ AzureEnabled?: boolean;
21
+ AzureMonitorKey?: string;
22
+ }
23
+
24
+ /**
25
+ * The core setup for Azure Insights and opentelemetry for
26
+ * admin and storefront. Config can be extended to support multiple
27
+ * opentelemetry exports.
28
+ */
29
+ async function setupOtel(otelConfig?: otelConfig) {
30
+ if (!process.env.OTELCOL_URL) {
31
+ throw new Error("Missing OTELCOL_URL environment variable.");
32
+ }
33
+
34
+ const { serviceName, AzureEnabled, AzureMonitorKey } = otelConfig ?? {};
35
+
36
+ if (!AzureEnabled) {
37
+ return registerOTel({
38
+ serviceName: otelConfig?.serviceName,
39
+ spanProcessors: [
40
+ new BatchSpanProcessor(
41
+ new OTLPTraceExporter({ url: process.env.OTELCOL_URL }),
42
+ ),
43
+ ],
44
+ });
45
+ }
46
+
47
+ /** Azure Enabled */
48
+ if (!AzureMonitorKey)
49
+ throw new Error("No Azure Monitor Connection String Provided.");
50
+
51
+ const connectionString = AzureMonitorKey;
52
+ const config = { connectionString };
53
+
54
+ // Azure - Imports
55
+ const {
56
+ AzureMonitorMetricExporter,
57
+ AzureMonitorTraceExporter,
58
+ AzureMonitorLogExporter,
59
+ } = await import("@azure/monitor-opentelemetry-exporter");
60
+ const { HostMetrics } = await import("@opentelemetry/host-metrics");
61
+
62
+ // Azure - Monitor Exporters
63
+ const metricsExporter = new AzureMonitorMetricExporter(config);
64
+ const logExporter = new AzureMonitorLogExporter(config);
65
+ const traceExporter = new AzureMonitorTraceExporter(config);
66
+
67
+ // Azure - Logging
68
+ const logProcessor = new BatchLogRecordProcessor(logExporter, {
69
+ maxExportBatchSize: 100,
70
+ });
71
+ const loggerProvider = new LoggerProvider({ processors: [logProcessor] });
72
+ logs.setGlobalLoggerProvider(loggerProvider);
73
+
74
+ // Azure - Metrics
75
+ const metricReaderOptions = {
76
+ exporter: metricsExporter,
77
+ };
78
+ const metricReader = new PeriodicExportingMetricReader(metricReaderOptions);
79
+ const meterProvider = new MeterProvider({
80
+ readers: [metricReader],
81
+ });
82
+ metrics.setGlobalMeterProvider(meterProvider);
83
+ // OS level Metrics
84
+ const hostMetrics = new HostMetrics({ meterProvider });
85
+ hostMetrics.start();
86
+
87
+ /** NextJS Otel Registration */
88
+ registerOTel({
89
+ serviceName: serviceName,
90
+ spanProcessors: [
91
+ new BatchSpanProcessor(traceExporter),
92
+ new BatchSpanProcessor(
93
+ new OTLPTraceExporter({ url: process.env.OTELCOL_URL }),
94
+ ),
95
+ ],
96
+ });
97
+ }
98
+
99
+ export { setupOtel };
package/tsconfig.json CHANGED
@@ -10,10 +10,11 @@
10
10
  "moduleResolution": "node",
11
11
  "resolveJsonModule": true,
12
12
  "outDir": "./dist",
13
- "baseUrl": "../../../../storefront/",
13
+ "baseUrl": "./",
14
14
  "jsx": "preserve",
15
+ "typeRoots": ["../../../../storefront/node_modules/@types"],
15
16
  "paths": {
16
- "*": ["../../../../storefront/node_modules/"]
17
+ "*": ["../../../../storefront/node_modules/*"]
17
18
  }
18
19
  },
19
20
  "include": ["./"]