diff --git a/CHANGELOG.md b/CHANGELOG.md index 19ec80f..256bfc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,20 @@ הספריה עוקבת אחרי [Semantic Versioning](https://semver.org) ([עברית](https://semver.org/lang/he/)). +## ‏6.3.0 + +- נוספה אופציה `logTimestamps` להוספת חותמות זמן (timestamps) בפורמט ISO להודעות הלוג שהספרייה מדפיסה + - ברירת מחדל: `false` (כדי לשמור על תאימות לאחור) + - שימושי במיוחד בסביבות production כמו Kubernetes שבהן חשוב לראות מתי בדיוק כל פעולה התרחשה + - דוגמה לשימוש: + ```javascript + const router = YemotRouter({ + printLog: true, + logTimestamps: true + }); + ``` + - פורמט הלוג עם timestamps: `[2025-11-06T17:56:55.068Z] [call-id]: message` + ## ‏6.2.0 - נוסף טייפ `SYSTEM_MESSAGE_CODES` עבור הודעות מערכת, המספק גם בטיחות מפני טעות הקלדה וגם הצגת תיאור ההודעה בריחוף על שמה diff --git a/README.md b/README.md index a638b14..6a14aa0 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ router.get('/', async (call) => { ‫מכסה גם מקרי קצה שלא התקבלה מימות הקריאה עם hangup=yes.
‫יש לשים לב לא להגדיר ערך נמוך שמחייג לגיטימי שלא הקיש מיד תשובה עלול להיתקל ב-timeout. - **printLog** (בוליאני): האם להדפיס לוג מפורט על כל קריאה לשרת, ניתוק שיחה וכולי. שימושי לפיתוח. +- **logTimestamps** (בוליאני): האם להוסיף חותמות זמן (timestamps) בפורמט ISO להודעות הלוג שהספרייה מדפיסה. ברירת מחדל: `false`. שימושי במיוחד בסביבות production כמו Kubernetes שבהן חשוב לראות מתי בדיוק כל פעולה התרחשה. - **uncaughtErrorHandler**: (פונקציה) ‫ פונקציה לטיפול בשגיאות לא מטופלות בתוך שיחה, שימושי לדוגמה לשמירת לוג + השמעת הודעה למשתמש, במקום קריסה של השרת, והמשתמש ישמע "אין מענה משרת API". ראה דוגמה ב[example.js](example.js). diff --git a/example-timestamps.js b/example-timestamps.js new file mode 100644 index 0000000..6c696b0 --- /dev/null +++ b/example-timestamps.js @@ -0,0 +1,34 @@ +import express from 'express'; +import { YemotRouter } from './index.js'; + +const app = express(); +app.use(express.urlencoded({ extended: true })); + +// דוגמה עם timestamps מופעלים +const router = YemotRouter({ + printLog: true, + logTimestamps: true // 👈 הפעלת timestamps +}); + +router.get('/', async (call) => { + const response = await call.read([{ + type: 'text', + data: 'שלום, הקש 1 להמשך' + }], 'tap', { + max_digits: 1, + digits_allowed: [1] + }); + + return call.id_list_message([{ + type: 'text', + data: 'תודה, להתראות' + }]); +}); + +app.use(router); + +const PORT = 9770; +app.listen(PORT, () => { + console.log(`Server running on port ${PORT}`); + console.log(`Example with timestamps enabled`); +}); diff --git a/index.d.ts b/index.d.ts index ea0884c..c477f86 100644 --- a/index.d.ts +++ b/index.d.ts @@ -44,6 +44,12 @@ interface Defaults { * @default false */ printLog?: boolean + /** + * האם להוסיף חותמות זמן (timestamps) בפורמט ISO להודעות הלוג של הספרייה
+ * שימושי במיוחד בסביבות production כמו Kubernetes
+ * @default false + */ + logTimestamps?: boolean /** * האם להסיר אוטומטית תווים לא חוקיים (`.`,`-`,`'`,`"`,`&`) מתשובות הקראת טקסט
* ,באם לא מוגדרת הסרה (ברירת מחדל), תיזרק שגיאה
diff --git a/lib/call.js b/lib/call.js index 7853e92..7143fa1 100644 --- a/lib/call.js +++ b/lib/call.js @@ -76,7 +76,8 @@ class Call { #logger (msg, color = 'blue') { if (!this.#defaults.printLog) return; - console.log(colors[color](`[${this.callId}]: ${msg}`)); + const timestamp = this.#defaults.logTimestamps ? `[${new Date().toISOString()}] ` : ''; + console.log(colors[color](`${timestamp}[${this.callId}]: ${msg}`)); } async read (messages, mode = 'tap', options = {}) { diff --git a/lib/defaults.js b/lib/defaults.js index 4db9878..0e8e4e4 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -1,5 +1,6 @@ export default { printLog: false, + logTimestamps: false, removeInvalidChars: false, read: { // val_name is dynamic generated diff --git a/lib/yemot_router.js b/lib/yemot_router.js index f239cff..8595e6c 100644 --- a/lib/yemot_router.js +++ b/lib/yemot_router.js @@ -10,6 +10,7 @@ import { parse as parseStack } from 'stack-trace'; function YemotRouter (options = {}) { const ops = { printLog: options.printLog, + logTimestamps: options.logTimestamps, timeout: options.timeout, uncaughtErrorHandler: options.uncaughtErrorHandler || null, defaults: options.defaults || {} @@ -29,6 +30,7 @@ function YemotRouter (options = {}) { let mergedDefaults = { printLog: ops.printLog ?? globalDefaults.printLog, + logTimestamps: ops.logTimestamps ?? globalDefaults.logTimestamps, removeInvalidChars: ops.defaults?.removeInvalidChars ?? globalDefaults.removeInvalidChars, read: { timeout: ops.timeout ?? globalDefaults.read.timeout, @@ -56,7 +58,8 @@ function YemotRouter (options = {}) { function logger (callId, msg, color = 'blue') { if (!(ops.printLog ?? mergedDefaults.printLog)) return; - console.log(colors[color](`[${callId}]: ${msg}`)); + const timestamp = (ops.logTimestamps ?? mergedDefaults.logTimestamps) ? `[${new Date().toISOString()}] ` : ''; + console.log(colors[color](`${timestamp}[${callId}]: ${msg}`)); } function deleteCall (callId) { @@ -95,7 +98,8 @@ function YemotRouter (options = {}) { const [trace] = parseStack(err); const errorPath = `${trace.getFileName()}:${trace.getLineNumber()}:${trace.getColumnNumber()}`; if (err instanceof ExitError) { - console.log(`👋 the call was exited from the extension /${call.extension} in uncaughtErrorHandler ${errorPath}` + (error.context ? ` (by ${error.context?.caller} to ${error.context?.target})` : '')); + const timestamp = (ops.logTimestamps ?? mergedDefaults.logTimestamps) ? `[${new Date().toISOString()}] ` : ''; + console.log(`${timestamp}👋 the call was exited from the extension /${call.extension} in uncaughtErrorHandler ${errorPath}` + (error.context ? ` (by ${error.context?.caller} to ${error.context?.target})` : '')); } else { console.error('💥 Error in uncaughtErrorHandler! process is crashing'); throw err; diff --git a/package.json b/package.json index bdade33..52d6ffb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yemot-router2", - "version": "6.2.0", + "version": "6.3.0", "description": "", "exports": { "import": "./index.js",