plutin 1.5.4 → 1.6.1

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/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  import { Express } from 'express';
3
- import { FastifyInstance } from 'fastify';
3
+ import { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
4
+ import { Logger } from '@opentelemetry/api-logs';
5
+ import winston from 'winston';
4
6
 
5
7
  type AnyObject = Record<string, any>;
6
8
  type Request = {
@@ -269,13 +271,27 @@ declare const baseEnvSchema: z.ZodObject<{
269
271
  SHOULD_NOTIFY_ERROR: z.ZodDefault<z.ZodBoolean>;
270
272
  SENTRY_DSN: z.ZodOptional<z.ZodString>;
271
273
  DISCORD_WEBHOOK_URL: z.ZodOptional<z.ZodString>;
274
+ LOG_LEVEL: z.ZodDefault<z.ZodEnum<["info", "error", "debug", "fatal", "warn"]>>;
275
+ OTEL_ENABLE: z.ZodDefault<z.ZodBoolean>;
276
+ OTEL_SERVICE_NAME: z.ZodOptional<z.ZodString>;
277
+ OTEL_SERVICE_VERSION: z.ZodOptional<z.ZodString>;
278
+ OTEL_OTLP_TRACES_EXPORTER_URL: z.ZodOptional<z.ZodString>;
279
+ OTEL_OTLP_LOGS_EXPORTER_URL: z.ZodOptional<z.ZodString>;
280
+ OTEL_OTLP_METRICS_EXPORTER_URL: z.ZodOptional<z.ZodString>;
272
281
  }, "strip", z.ZodTypeAny, {
273
282
  ENVIRONMENT: "test" | "development" | "production" | "staging";
274
283
  SHOULD_NOTIFY_ERROR: boolean;
275
284
  NODE_ENV: "test" | "development" | "production";
276
285
  PORT: number;
286
+ LOG_LEVEL: "error" | "fatal" | "warn" | "info" | "debug";
287
+ OTEL_ENABLE: boolean;
277
288
  SENTRY_DSN?: string | undefined;
278
289
  DISCORD_WEBHOOK_URL?: string | undefined;
290
+ OTEL_SERVICE_NAME?: string | undefined;
291
+ OTEL_SERVICE_VERSION?: string | undefined;
292
+ OTEL_OTLP_TRACES_EXPORTER_URL?: string | undefined;
293
+ OTEL_OTLP_LOGS_EXPORTER_URL?: string | undefined;
294
+ OTEL_OTLP_METRICS_EXPORTER_URL?: string | undefined;
279
295
  }, {
280
296
  ENVIRONMENT?: "test" | "development" | "production" | "staging" | undefined;
281
297
  SHOULD_NOTIFY_ERROR?: boolean | undefined;
@@ -283,6 +299,13 @@ declare const baseEnvSchema: z.ZodObject<{
283
299
  PORT?: number | undefined;
284
300
  SENTRY_DSN?: string | undefined;
285
301
  DISCORD_WEBHOOK_URL?: string | undefined;
302
+ LOG_LEVEL?: "error" | "fatal" | "warn" | "info" | "debug" | undefined;
303
+ OTEL_ENABLE?: boolean | undefined;
304
+ OTEL_SERVICE_NAME?: string | undefined;
305
+ OTEL_SERVICE_VERSION?: string | undefined;
306
+ OTEL_OTLP_TRACES_EXPORTER_URL?: string | undefined;
307
+ OTEL_OTLP_LOGS_EXPORTER_URL?: string | undefined;
308
+ OTEL_OTLP_METRICS_EXPORTER_URL?: string | undefined;
286
309
  }>;
287
310
 
288
311
  type OptionsNotifications = 'console' | 'discord' | 'sentry';
@@ -308,6 +331,52 @@ declare class SentryNotifier implements IErrorNotifier {
308
331
  notify(error: Error, context: ContextError): Promise<void>;
309
332
  }
310
333
 
334
+ declare class WinstonOtelFastify {
335
+ private readonly env;
336
+ logger: Logger;
337
+ consoleLogger: winston.Logger;
338
+ level: 'info' | 'error' | 'debug' | 'fatal' | 'warn';
339
+ constructor(env: Record<string, any>);
340
+ private bodyIsFastifyRequest;
341
+ private bodyIsFastifyReply;
342
+ private buildMessage;
343
+ private logMessage;
344
+ info(body: string | {
345
+ req?: FastifyRequest;
346
+ res?: FastifyReply;
347
+ }): void;
348
+ error(body: string | {
349
+ req?: FastifyRequest;
350
+ res?: FastifyReply;
351
+ }): void;
352
+ debug(body: string | {
353
+ req?: FastifyRequest;
354
+ res?: FastifyReply;
355
+ }): void;
356
+ fatal(body: string | {
357
+ req?: FastifyRequest;
358
+ res?: FastifyReply;
359
+ }): void;
360
+ warn(body: string | {
361
+ req?: FastifyRequest;
362
+ res?: FastifyReply;
363
+ }): void;
364
+ trace(message: string): void;
365
+ child(): WinstonOtelFastify;
366
+ }
367
+
368
+ declare function Span(): MethodDecorator;
369
+
370
+ interface ITracerGateway {
371
+ addEvent(name: string, attributes?: Record<string, any>): void;
372
+ setAttribute(key: string, value: string | number | boolean): void;
373
+ }
374
+
375
+ declare class TracerGatewayOpentelemetry implements ITracerGateway {
376
+ addEvent(name: string, attributes?: Record<string, any>): void;
377
+ setAttribute(key: string, value: string | number | boolean): void;
378
+ }
379
+
311
380
  declare const logger: {
312
381
  info: (...args: any[]) => void;
313
382
  log: (...args: any[]) => void;
@@ -315,4 +384,4 @@ declare const logger: {
315
384
  error: (...args: any[]) => void;
316
385
  };
317
386
 
318
- export { AggregateObjectRoot, AggregateRoot, BaseController, CommonDTO, ContextError, Controller, CreateCommonDTO, DependencyContainer, DiscordNotifier, DtoResponsePagination, Entity, EntityObject, ExpressAdapter, FastifyAdapter, GlobalErrorHandler, IErrorNotifier, IHealthCheckDB, IHttp, Inject, MethodType, MiddlewareFunction, NotPagination, NotificationErrorInMemory, NotificationFactory, Optional, Pagination, Replace, Request, RequestHttp, Response, SentryNotifier, UniqueEntityId, UniqueObjectId, ValueObject, WatchedList, ZodSchema, baseEnvSchema, getTakeAndSkip, logger, zodValidator };
387
+ export { AggregateObjectRoot, AggregateRoot, BaseController, CommonDTO, ContextError, Controller, CreateCommonDTO, DependencyContainer, DiscordNotifier, DtoResponsePagination, Entity, EntityObject, ExpressAdapter, FastifyAdapter, GlobalErrorHandler, IErrorNotifier, IHealthCheckDB, IHttp, ITracerGateway, Inject, MethodType, MiddlewareFunction, NotPagination, NotificationErrorInMemory, NotificationFactory, Optional, Pagination, Replace, Request, RequestHttp, Response, SentryNotifier, Span, TracerGatewayOpentelemetry, UniqueEntityId, UniqueObjectId, ValueObject, WatchedList, WinstonOtelFastify, ZodSchema, baseEnvSchema, getTakeAndSkip, logger, zodValidator };
package/dist/index.mjs CHANGED
@@ -1456,6 +1456,198 @@ function zodValidator(schema) {
1456
1456
  }
1457
1457
  __name(zodValidator, "zodValidator");
1458
1458
 
1459
+ // src/infra/adapters/logger/winston-otel-fastify.ts
1460
+ import opentelemetry from "@opentelemetry/api";
1461
+ import { logs, SeverityNumber } from "@opentelemetry/api-logs";
1462
+ import winston from "winston";
1463
+ var WinstonOtelFastify = class WinstonOtelFastify2 {
1464
+ static {
1465
+ __name(this, "WinstonOtelFastify");
1466
+ }
1467
+ env;
1468
+ logger;
1469
+ consoleLogger;
1470
+ level;
1471
+ constructor(env) {
1472
+ this.env = env;
1473
+ this.level = "info";
1474
+ if (env.OTEL_ENABLE) {
1475
+ this.logger = logs.getLogger(this.env.OTEL_SERVICE_NAME, this.env.OTEL_SERVICE_VERSION);
1476
+ this.level = this.env.LOG_LEVEL;
1477
+ const transports = this.env.NODE_ENV === "test" ? [
1478
+ new winston.transports.Console({
1479
+ silent: true
1480
+ })
1481
+ ] : [
1482
+ new winston.transports.Console()
1483
+ ];
1484
+ this.consoleLogger = winston.createLogger({
1485
+ level: this.level,
1486
+ format: winston.format.combine(winston.format.timestamp({
1487
+ format: "YYYY-MM-DD HH:mm:ss:ms"
1488
+ }), winston.format((info) => {
1489
+ if (this.env.NODE_ENV !== "test") {
1490
+ const span = opentelemetry.trace.getActiveSpan();
1491
+ if (span) {
1492
+ info.spanId = span.spanContext().spanId;
1493
+ info.traceId = span.spanContext().traceId;
1494
+ }
1495
+ }
1496
+ return info;
1497
+ })(), winston.format.json()),
1498
+ transports
1499
+ });
1500
+ } else {
1501
+ this.consoleLogger = winston.createLogger({
1502
+ level: this.level,
1503
+ format: winston.format.combine(winston.format.timestamp({
1504
+ format: "YYYY-MM-DD HH:mm:ss:ms"
1505
+ }), winston.format.json())
1506
+ });
1507
+ }
1508
+ }
1509
+ bodyIsFastifyRequest(body) {
1510
+ return body.method !== void 0;
1511
+ }
1512
+ bodyIsFastifyReply(body) {
1513
+ return body.statusCode !== void 0;
1514
+ }
1515
+ buildMessage(body) {
1516
+ if (typeof body === "object" && body.req && this.bodyIsFastifyRequest(body.req)) {
1517
+ return `${body.req.method} ${body.req.url}`;
1518
+ } else if (typeof body === "object" && body.res && this.bodyIsFastifyReply(body.res)) {
1519
+ return `${body.res.request.method} ${body.res.request.url} ${body.res.statusCode} - ${body.res.elapsedTime} ms`;
1520
+ } else if (typeof body === "string") {
1521
+ return body;
1522
+ } else {
1523
+ return "";
1524
+ }
1525
+ }
1526
+ logMessage(body, severityNumber, severityText) {
1527
+ const message = this.buildMessage(body);
1528
+ this.consoleLogger[severityText.toLowerCase()](message);
1529
+ if (this.env.NODE_ENV !== "test") {
1530
+ this.logger.emit({
1531
+ body: message,
1532
+ severityNumber,
1533
+ severityText
1534
+ });
1535
+ }
1536
+ }
1537
+ info(body) {
1538
+ this.logMessage(body, SeverityNumber.INFO, "INFO");
1539
+ }
1540
+ error(body) {
1541
+ this.logMessage(body, SeverityNumber.ERROR, "ERROR");
1542
+ }
1543
+ debug(body) {
1544
+ this.logMessage(body, SeverityNumber.DEBUG, "DEBUG");
1545
+ }
1546
+ fatal(body) {
1547
+ this.logMessage(body, SeverityNumber.FATAL, "FATAL");
1548
+ }
1549
+ warn(body) {
1550
+ this.logMessage(body, SeverityNumber.WARN, "WARN");
1551
+ }
1552
+ trace(message) {
1553
+ if (this.env.NODE_ENV !== "test") {
1554
+ this.logger.emit({
1555
+ body: message,
1556
+ severityNumber: SeverityNumber.TRACE,
1557
+ severityText: "TRACE"
1558
+ });
1559
+ }
1560
+ }
1561
+ child() {
1562
+ return new WinstonOtelFastify2(process.env);
1563
+ }
1564
+ };
1565
+
1566
+ // src/infra/adapters/observability/otel/span-decorator.ts
1567
+ import opentelemetry2, { SpanStatusCode } from "@opentelemetry/api";
1568
+ import "reflect-metadata";
1569
+ function Span() {
1570
+ return function(target, propertyKey, descriptor) {
1571
+ if (!process.env.OTEL_ENABLE) {
1572
+ return descriptor;
1573
+ }
1574
+ const originalMethod = descriptor.value;
1575
+ descriptor.value = function(...args) {
1576
+ const tracer = opentelemetry2.trace.getTracer(process.env.OTEL_SERVICE_NAME, process.env.OTEL_SERVICE_VERSION);
1577
+ const className = target.constructor?.name || "UnknownClass";
1578
+ const methodName = String(propertyKey);
1579
+ const spanName = `${className}.${methodName}`;
1580
+ return tracer.startActiveSpan(spanName, async (span) => {
1581
+ try {
1582
+ const result = originalMethod.apply(this, args);
1583
+ if (result instanceof Promise) {
1584
+ try {
1585
+ const awaitedResult = await result;
1586
+ span.addEvent(`Method [${methodName}] executed successfully`);
1587
+ span.end();
1588
+ return awaitedResult;
1589
+ } catch (error) {
1590
+ handleSpanError(span, error);
1591
+ throw error;
1592
+ }
1593
+ } else {
1594
+ span.addEvent(`Method [${methodName}] executed successfully`);
1595
+ span.end();
1596
+ return result;
1597
+ }
1598
+ } catch (error) {
1599
+ handleSpanError(span, error);
1600
+ throw error;
1601
+ }
1602
+ });
1603
+ };
1604
+ return descriptor;
1605
+ };
1606
+ }
1607
+ __name(Span, "Span");
1608
+ function handleSpanError(span, error) {
1609
+ const errorMessage = error instanceof Error ? error.message : String(error);
1610
+ if (error instanceof Error) {
1611
+ span.recordException(error);
1612
+ } else {
1613
+ span.recordException(new Error(String(error)));
1614
+ }
1615
+ span.setStatus({
1616
+ code: SpanStatusCode.ERROR,
1617
+ message: errorMessage
1618
+ });
1619
+ span.end();
1620
+ }
1621
+ __name(handleSpanError, "handleSpanError");
1622
+
1623
+ // src/infra/adapters/observability/otel/tracer-gateway-opentelemetry.ts
1624
+ import opentelemetry3 from "@opentelemetry/api";
1625
+ var TracerGatewayOpentelemetry = class {
1626
+ static {
1627
+ __name(this, "TracerGatewayOpentelemetry");
1628
+ }
1629
+ addEvent(name, attributes) {
1630
+ if (!process.env.OTEL_ENABLE) {
1631
+ return;
1632
+ }
1633
+ const span = opentelemetry3.trace.getActiveSpan();
1634
+ if (span && attributes) {
1635
+ span.addEvent(name, attributes);
1636
+ } else if (span) {
1637
+ span.addEvent(name);
1638
+ }
1639
+ }
1640
+ setAttribute(key, value) {
1641
+ if (!process.env.OTEL_ENABLE) {
1642
+ return;
1643
+ }
1644
+ const span = opentelemetry3.trace.getActiveSpan();
1645
+ if (span) {
1646
+ span.setAttribute(key, value);
1647
+ }
1648
+ }
1649
+ };
1650
+
1459
1651
  // src/infra/env/index.ts
1460
1652
  import { z } from "zod";
1461
1653
 
@@ -1480,7 +1672,20 @@ var baseEnvSchema = z.object({
1480
1672
  PORT: z.coerce.number().default(3333),
1481
1673
  SHOULD_NOTIFY_ERROR: z.coerce.boolean().default(true),
1482
1674
  SENTRY_DSN: z.string().optional(),
1483
- DISCORD_WEBHOOK_URL: z.string().optional()
1675
+ DISCORD_WEBHOOK_URL: z.string().optional(),
1676
+ LOG_LEVEL: z.enum([
1677
+ "info",
1678
+ "error",
1679
+ "debug",
1680
+ "fatal",
1681
+ "warn"
1682
+ ]).default("info"),
1683
+ OTEL_ENABLE: z.coerce.boolean().default(false),
1684
+ OTEL_SERVICE_NAME: z.string().optional(),
1685
+ OTEL_SERVICE_VERSION: z.string().optional(),
1686
+ OTEL_OTLP_TRACES_EXPORTER_URL: z.string().url().optional(),
1687
+ OTEL_OTLP_LOGS_EXPORTER_URL: z.string().url().optional(),
1688
+ OTEL_OTLP_METRICS_EXPORTER_URL: z.string().url().optional()
1484
1689
  });
1485
1690
  export {
1486
1691
  AggregateObjectRoot,
@@ -1498,10 +1703,13 @@ export {
1498
1703
  NotificationErrorInMemory,
1499
1704
  NotificationFactory,
1500
1705
  SentryNotifier,
1706
+ Span,
1707
+ TracerGatewayOpentelemetry,
1501
1708
  UniqueEntityId,
1502
1709
  UniqueObjectId,
1503
1710
  ValueObject,
1504
1711
  WatchedList,
1712
+ WinstonOtelFastify,
1505
1713
  baseEnvSchema,
1506
1714
  getTakeAndSkip,
1507
1715
  logger,