log.utils.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import fs from "fs";
  2. import "source-map-support/register";
  3. // const chalk = require('chalk');
  4. import chalk from 'chalk'
  5. // const logColors: Record<string, (text: string) => string> = {
  6. // base: chalk.bgRgb(69, 64, 74),
  7. // managers: chalk.bgRgb(128, 20, 217),
  8. // transmission: chalk.bgRgb(0, 106, 255),
  9. // adapter: chalk.bgRgb(51, 130, 68),
  10. // transport: chalk.bgRgb(173, 9, 0),
  11. // error: chalk.rgb(212, 32, 0),
  12. // util: chalk.rgb(200, 204, 177),
  13. // details: chalk.rgb(255, 255, 97),
  14. // location: chalk.rgb(241, 112, 255),
  15. // retransmission: chalk.bgRgb(186, 87, 0)
  16. // };
  17. function applyColor(rgb: [number, number, number], isBackground: boolean = false) {
  18. const [r, g, b] = rgb;
  19. return isBackground ? chalk.bgRgb(r, g, b) : chalk.rgb(r, g, b);
  20. }
  21. const logColors: Record<string, [number, number, number]> = {
  22. base: [69, 64, 74],
  23. managers: [128, 20, 217],
  24. transmission: [0, 106, 255],
  25. adapter: [51, 130, 68],
  26. transport: [173, 9, 0],
  27. error: [212, 32, 0],
  28. util: [200, 204, 177],
  29. details: [255, 255, 97],
  30. retransmission: [186, 87, 0],
  31. };
  32. class ConsoleLogger {
  33. private categoryPath: string[] = []
  34. private settings: Record<string, any>;
  35. private className!: string
  36. constructor(className: string, categoryPath: string[]) {
  37. this.className = className
  38. let configPath = "./logSetting.json"
  39. this.settings = this.loadSettings(configPath);
  40. this.categoryPath = categoryPath
  41. }
  42. private loadSettings(configPath: string): Record<string, any> {
  43. try {
  44. const config = fs.readFileSync(configPath, "utf-8");
  45. return JSON.parse(config);
  46. } catch (error) {
  47. console.error("Failed to load log settings:", error);
  48. return {};
  49. }
  50. }
  51. private isCategoryEnabled(categoryPath: string[]): boolean {
  52. let currentLevel = this.settings;
  53. for (const part of categoryPath) {
  54. if (currentLevel[part] === undefined) {
  55. return false; // Category or subcategory does not exist
  56. }
  57. if (typeof currentLevel[part] === "boolean") {
  58. return currentLevel[part];
  59. }
  60. currentLevel = currentLevel[part];
  61. }
  62. return false;
  63. }
  64. log(message: { message: string, details?: any }): void {
  65. if (!this.isCategoryEnabled(this.categoryPath)) {
  66. return; // Skip logging if the category is disabled
  67. }
  68. const category = this.categoryPath.join(" -> ").toUpperCase();
  69. const location = this.getLogLocation();
  70. const primaryCategory = this.categoryPath[0];
  71. const rgb = logColors[primaryCategory] || [255, 255, 255]; // Default to white
  72. const categoryStyle = applyColor(rgb, true); // Use bgRgb for category
  73. const locationStyle = applyColor(rgb); // Use rgb for location
  74. const formattedCategory = categoryStyle(`[${category}]`);
  75. const formattedClassName = categoryStyle(`${this.className}`);
  76. const formattedLocation = locationStyle(` ${location}`);
  77. const formattedMessage = `${formattedClassName}${formattedLocation}: ${message.message}`;
  78. console.log(formattedMessage, message.details ? applyColor([255, 255, 97])(message.details) : '');
  79. if (message.details && this.isCategoryEnabled(["details"])) {
  80. console.log(applyColor([255, 255, 97])('Details: '), message.details);
  81. }
  82. }
  83. error(message: { message: string, details?: any }): void {
  84. if (!this.isCategoryEnabled(this.categoryPath)) {
  85. return; // Skip logging if the category is disabled
  86. }
  87. const category = this.categoryPath.join(" -> ").toUpperCase();
  88. const location = this.getLogLocation();
  89. const primaryCategory = this.categoryPath[0];
  90. const rgb = logColors[primaryCategory] || [255, 255, 255]; // Default to white
  91. const categoryStyle = applyColor(rgb, true); // Use bgRgb for category
  92. const locationStyle = applyColor(rgb); // Use rgb for location
  93. const messageStyle = applyColor([224, 0, 0])
  94. const formattedCategory = categoryStyle(`[${category}]`);
  95. const formattedClassName = categoryStyle(`${this.className}`);
  96. const formattedLocation = locationStyle(`${location}`);
  97. const formattedErrorMessage = messageStyle(`${message.message}`)
  98. const formattedMessage = `${formattedClassName} ${formattedLocation}: ${formattedErrorMessage}`;
  99. console.log(formattedMessage, message.details ? applyColor([224, 0, 0])(message.details) : '');
  100. if (message.details && this.isCategoryEnabled(["details"])) {
  101. console.log(applyColor([224, 0, 0])('Details: '), message.details);
  102. }
  103. }
  104. reloadSettings(configPath: string): void {
  105. this.settings = this.loadSettings(configPath);
  106. }
  107. private getLogLocation(): string {
  108. if (!this.isCategoryEnabled(["location"])) {
  109. return ""; // Don't display location if the category is disabled
  110. }
  111. const error = new Error();
  112. // Captures the current stack trace
  113. Error.captureStackTrace(error, this.getLogLocation);
  114. const stack = error.stack?.split("\n") || [];
  115. const callerLine = stack[2]; // Adjust index to get the correct caller line (this may vary based on environment)
  116. // Extract only line and column numbers using regex
  117. const match = callerLine?.match(/:(\d+):(\d+)\)/);
  118. if (match) {
  119. const [, line, column] = match;
  120. // return `line ${line}, column ${column}`;
  121. return `at line ${line}`;
  122. }
  123. return "at unknown location";
  124. }
  125. }
  126. export default ConsoleLogger;