90 lines
2.1 KiB
JavaScript
90 lines
2.1 KiB
JavaScript
const sqlite3 = require('better-sqlite3')
|
|
|
|
const db = sqlite3(`./data/log.sqlite`)
|
|
db.pragma('journal_mode = DELETE')
|
|
db.pragma('synchronous = 0')
|
|
|
|
db.exec(`
|
|
create table if not exists http (time integer default (strftime('%s','now')), method text, url text, headers text, body text, status text, duration integer);
|
|
create table if not exists mtproto (time integer default (strftime('%s','now')), message text);
|
|
create table if not exists error (time integer default (strftime('%s','now')), message text, stack text);
|
|
`)
|
|
|
|
function http (req, res, duration) {
|
|
const data = {
|
|
method: req.method,
|
|
url: req.url,
|
|
status: res.statusCode,
|
|
duration
|
|
};
|
|
|
|
['headers', 'body'].forEach(key => {
|
|
const value = req.body[key]
|
|
try {
|
|
data[key] = value instanceof Array && value.length < 1_000_000 || value instanceof Object ? JSON.stringify(value) : value?.toString() || null
|
|
} catch (err) {
|
|
error(err)
|
|
data[key] = value?.toString() || null
|
|
}
|
|
})
|
|
|
|
db
|
|
.prepare(`insert into http (method, url, headers, body, status, duration) values (:method, :url, :headers, :body, :status, :duration)`)
|
|
.run(data)
|
|
}
|
|
|
|
function safeStringify(obj, indent = 2) {
|
|
const cache = new Set()
|
|
|
|
return JSON.stringify(obj, (key, value) => {
|
|
if (typeof value === 'object' && value !== null) {
|
|
if (cache.has(value))
|
|
return '[Circular]'
|
|
|
|
cache.add(value)
|
|
}
|
|
|
|
return value
|
|
}, indent)
|
|
}
|
|
|
|
function mtproto (update) {
|
|
const message = update
|
|
message.self = message
|
|
|
|
db
|
|
.prepare(`insert into mtproto (message) values (:message)`)
|
|
.run({
|
|
message: safeStringify(message)
|
|
})
|
|
}
|
|
|
|
function error (...args) {
|
|
const stacks = []
|
|
const message = args.map(arg => {
|
|
if (arg instanceof Error) {
|
|
stacks.push(arg.stack)
|
|
return 'Error: ' + arg.message
|
|
} else if (arg instanceof Object) {
|
|
try {
|
|
return JSON.stringify(arg)
|
|
} catch (err) { }
|
|
}
|
|
|
|
return String(arg)
|
|
}).join('\n')
|
|
|
|
if (stacks.length == 0)
|
|
stacks.push(new Error().stack)
|
|
|
|
console.error(message)
|
|
|
|
db
|
|
.prepare(`insert into error (message, stack) values (:message, :stack)`)
|
|
.run({
|
|
message,
|
|
stack: stacks.join('\n\n')
|
|
})
|
|
}
|
|
|
|
module.exports = { http, mtproto, error } |