125 lines
3.7 KiB
TypeScript
125 lines
3.7 KiB
TypeScript
import fs from 'node:fs'
|
||
import path from 'node:path'
|
||
|
||
/**
|
||
* Function to clean up unwanted characters from the output data.
|
||
* @param {string} data - The raw data to be cleaned.
|
||
* @returns {string} - The cleaned data.
|
||
*/
|
||
export const cleanData = (data: string) => {
|
||
return (
|
||
data
|
||
// 1️⃣ Xóa chuỗi "--More--" (Cisco/Unix pager)
|
||
.replace(/--More--[\s\x08\x1b\[K]*/g, '')
|
||
|
||
// 2️⃣ Xóa toàn bộ chuỗi ANSI escape sequences
|
||
// Ví dụ: ESC[2J, ESC[K, ESC[?25h, ESC[0m, ...
|
||
.replace(/\x1B\[[0-9;?]*[A-Za-z]/g, '')
|
||
|
||
// 3️⃣ Xóa ký tự Backspace (BS) hoặc Delete (DEL)
|
||
.replace(/[\x08\x7F]/g, '')
|
||
|
||
// 4️⃣ Xóa ký tự NUL và các control char khác (trừ \r, \n, \t)
|
||
.replace(/[^\x09\x0A\x0D\x20-\x7E]/g, '')
|
||
)
|
||
|
||
// 5️⃣ Chuẩn hóa xuống dòng nếu cần
|
||
// .replace(/\r\n/g, '\n')
|
||
}
|
||
|
||
export function sleep(ms: number) {
|
||
return new Promise((resolve) => setTimeout(resolve, ms))
|
||
}
|
||
|
||
// 20250527-AUTO-Session.Station_1-13-192.168.171.9-2.log
|
||
// {DATE}-AUTO-Session.{Station name}-{Station ID}-{Station IP}-{Line number}.log
|
||
export function appendLog(
|
||
output: string,
|
||
stationId: number,
|
||
stationName: string,
|
||
stationIP: string,
|
||
lineNumber: number
|
||
) {
|
||
const date = new Date().toISOString().slice(0, 10).replace(/-/g, '') // YYYYMMDD
|
||
const logDir = path.join('storage', 'system_logs')
|
||
const logFile = path
|
||
.join(logDir, `${date}-AUTO-Session.${stationName}-${stationId}-${stationIP}-${lineNumber}.log`)
|
||
.replaceAll(' ', '_')
|
||
|
||
// Ensure folder exists
|
||
if (!fs.existsSync(logDir)) {
|
||
fs.mkdirSync(logDir, { recursive: true })
|
||
}
|
||
|
||
fs.appendFile(logFile, output, (err) => {
|
||
if (err) {
|
||
console.error('❌ Failed to write log:', err.message)
|
||
}
|
||
})
|
||
}
|
||
|
||
export const getPathLog = (stationId: number, lineNumber: number, port: number) => {
|
||
const date = new Date().toISOString().slice(0, 10).replace(/-/g, '') // YYYYMMDD
|
||
const logDir = path.join('storage', 'system_logs')
|
||
const logFile = path.join(logDir, `${date}-Station_${stationId}-Line_${lineNumber}_${port}.log`)
|
||
// Ensure folder exists
|
||
if (!fs.existsSync(logDir)) {
|
||
fs.mkdirSync(logDir, { recursive: true })
|
||
return null
|
||
} else return logFile
|
||
}
|
||
|
||
/**
|
||
* Utility function get scope log with timestamp.
|
||
* @param {string} text - content log.
|
||
* @param {number} time - Timestamp.
|
||
*/
|
||
export const getLogWithTimeScenario = (text: string, time: number) => {
|
||
try {
|
||
// Match all start and end blocks
|
||
const regex = /---(start|end)-scenarios---(\d+)---/g
|
||
|
||
let match
|
||
const blocks = []
|
||
|
||
while ((match = regex.exec(text)) !== null) {
|
||
blocks.push({
|
||
type: match[1],
|
||
timestamp: match[2],
|
||
index: match.index,
|
||
})
|
||
}
|
||
|
||
// Find the matching block for the end timestamp
|
||
let result = null
|
||
for (let i = 0; i < blocks.length; i++) {
|
||
const block = blocks[i]
|
||
if (block.type === 'end' && block.timestamp === time.toString()) {
|
||
// Find nearest preceding "start"
|
||
for (let j = i - 1; j >= 0; j--) {
|
||
if (blocks[j].type === 'start') {
|
||
const startIndex = blocks[j].index
|
||
const endIndex = block.index + text.slice(block.index).indexOf('\n') // or manually offset length of the line
|
||
result = text.slice(startIndex, endIndex).trim()
|
||
break
|
||
}
|
||
}
|
||
break
|
||
}
|
||
}
|
||
return result
|
||
} catch (err) {
|
||
console.error('Error get log:', err)
|
||
return ''
|
||
}
|
||
}
|
||
|
||
export function isValidJson(string: string) {
|
||
try {
|
||
JSON.parse(string)
|
||
return true // Chuỗi là định dạng JSON hợp lệ
|
||
} catch (e) {
|
||
return false // Chuỗi không phải là định dạng JSON hợp lệ
|
||
}
|
||
}
|