mirror of
https://github.com/pockethost/pockethost.git
synced 2025-06-04 13:16:41 +00:00
feat: syslogd
This commit is contained in:
parent
7b9cbc3352
commit
34fe0fe43e
@ -20,6 +20,7 @@
|
||||
"POCKETSTREAM",
|
||||
"rizzdown",
|
||||
"superadmin",
|
||||
"syslogd",
|
||||
"unzipper",
|
||||
"upserting"
|
||||
]
|
||||
|
@ -12,6 +12,10 @@ module.exports = {
|
||||
name: `edge-ftp`,
|
||||
script: 'pnpm prod:edge:ftp',
|
||||
},
|
||||
{
|
||||
name: `edge-syslog`,
|
||||
script: 'pnpm prod:edge:syslog',
|
||||
},
|
||||
{
|
||||
name: `mothership`,
|
||||
script: 'pnpm prod:mothership',
|
||||
|
@ -24,12 +24,14 @@
|
||||
"dev:superadmin": "cd frontends/superadmin && pnpm dev",
|
||||
"dev:edge:daemon": "tsx watch src/cli/edge-daemon.ts",
|
||||
"dev:edge:ftp": "tsx watch src/cli/edge-ftp.ts",
|
||||
"dev:edge:syslogd": "tsx watch src/cli/edge-syslogd.ts",
|
||||
"dev:downloader": "pnpm download-versions",
|
||||
"dev:mothership:maildev": "npx -y maildev",
|
||||
"dev:mothership:pocketbase": "nodemon --signal SIGTERM --watch src --exec tsx ./src/cli/mothership.ts",
|
||||
"prod:proxy": "dotenv tsx ./src/cli/proxy/server.ts",
|
||||
"prod:edge:daemon": "tsx src/cli/edge-daemon.ts",
|
||||
"prod:edge:ftp": "tsx src/cli/edge-ftp.ts",
|
||||
"prod:edge:syslog": "tsx src/cli/edge-syslogd.ts",
|
||||
"prod:mothership": "tsx src/cli/mothership.ts",
|
||||
"plop": "plop",
|
||||
"nofile": "cat /proc/sys/fs/file-nr",
|
||||
@ -50,6 +52,7 @@
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@s-libs/micro-dash": "^16.1.0",
|
||||
"@types/winston-syslog": "^2.4.3",
|
||||
"ajv": "^8.12.0",
|
||||
"boolean": "^3.2.0",
|
||||
"bottleneck": "^2.19.5",
|
||||
@ -77,10 +80,12 @@
|
||||
"pocketbase": "^0.20.1",
|
||||
"semver": "^7.5.4",
|
||||
"sqlite3": "^5.1.6",
|
||||
"syslog-parse": "^2.0.0",
|
||||
"tail": "^2.2.6",
|
||||
"tmp": "^0.2.1",
|
||||
"url-pattern": "^1.0.3",
|
||||
"winston": "^3.11.0"
|
||||
"winston": "^3.11.0",
|
||||
"winston-syslog": "^2.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@swc/cli": "^0.1.62",
|
||||
|
72
pnpm-lock.yaml
generated
72
pnpm-lock.yaml
generated
@ -11,6 +11,9 @@ importers:
|
||||
'@s-libs/micro-dash':
|
||||
specifier: ^16.1.0
|
||||
version: 16.1.0
|
||||
'@types/winston-syslog':
|
||||
specifier: ^2.4.3
|
||||
version: 2.4.3
|
||||
ajv:
|
||||
specifier: ^8.12.0
|
||||
version: 8.12.0
|
||||
@ -92,6 +95,9 @@ importers:
|
||||
sqlite3:
|
||||
specifier: ^5.1.6
|
||||
version: 5.1.6
|
||||
syslog-parse:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
tail:
|
||||
specifier: ^2.2.6
|
||||
version: 2.2.6
|
||||
@ -104,6 +110,9 @@ importers:
|
||||
winston:
|
||||
specifier: ^3.11.0
|
||||
version: 3.11.0
|
||||
winston-syslog:
|
||||
specifier: ^2.7.0
|
||||
version: 2.7.0(winston@3.11.0)
|
||||
devDependencies:
|
||||
'@swc/cli':
|
||||
specifier: ^0.1.62
|
||||
@ -1421,6 +1430,12 @@ packages:
|
||||
resolution: {integrity: sha512-mZ0onxTS5OyfSwBNecTKT0h79e4XXHrc9RI5tQfEAf+Fp6NbBmNnc0kg59HO+97V+y3opS+sfo4k4qpYwLt6NQ==}
|
||||
dev: true
|
||||
|
||||
/@types/glossy@0.1.3:
|
||||
resolution: {integrity: sha512-CrdAR+ZgRf0MQnDAW4tUm2LpPmfC6sAWlrBwcX0O2oUKyZvseb6wlHZ0alo++DyaLckxqM4CUa+EfzyITJM7mA==}
|
||||
dependencies:
|
||||
'@types/node': 20.8.10
|
||||
dev: false
|
||||
|
||||
/@types/http-cache-semantics@4.0.3:
|
||||
resolution: {integrity: sha512-V46MYLFp08Wf2mmaBhvgjStM3tPa+2GAdy/iqoX+noX1//zje2x4XmrIU0cAwyClATsTmahbtoQ2EwP7I5WSiA==}
|
||||
dev: true
|
||||
@ -1527,7 +1542,6 @@ packages:
|
||||
resolution: {integrity: sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==}
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
dev: true
|
||||
|
||||
/@types/pug@2.0.8:
|
||||
resolution: {integrity: sha512-QzhsZ1dMGyJbn/D9V80zp4GIA4J4rfAjCCxc3MP+new0E8dyVdSkR735Lx+n3LIaHNFcjHL5+TbziccuT+fdoQ==}
|
||||
@ -1606,6 +1620,15 @@ packages:
|
||||
'@types/connect': 3.4.38
|
||||
dev: true
|
||||
|
||||
/@types/winston-syslog@2.4.3:
|
||||
resolution: {integrity: sha512-z9mO5hxDls4lSTth76sddIETonCMLguppeudk1YxBz4Y/OmdRkeKMfrOTfH74T9gN5WllLnF8XbHdiM8K6EL7A==}
|
||||
dependencies:
|
||||
'@types/glossy': 0.1.3
|
||||
'@types/node': 20.8.10
|
||||
winston: 3.11.0
|
||||
winston-transport: 4.6.0
|
||||
dev: false
|
||||
|
||||
/a-sync-waterfall@1.0.1:
|
||||
resolution: {integrity: sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==}
|
||||
dev: true
|
||||
@ -1961,6 +1984,14 @@ packages:
|
||||
resolution: {integrity: sha512-v4N2l3RxL+m4zDxyxz3Ne2aTmiPn8ZUpKFpdPtO+ItW1NcTCXA7JeHG5GMBSvoKSkQZ9ycS+EouDVxYB9ufKWA==}
|
||||
dev: true
|
||||
|
||||
/bindings@1.5.0:
|
||||
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
file-uri-to-path: 1.0.0
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/bl@1.2.3:
|
||||
resolution: {integrity: sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==}
|
||||
dependencies:
|
||||
@ -3491,6 +3522,12 @@ packages:
|
||||
engines: {node: '>=4'}
|
||||
dev: false
|
||||
|
||||
/file-uri-to-path@1.0.0:
|
||||
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/filelist@1.0.4:
|
||||
resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
|
||||
dependencies:
|
||||
@ -3890,6 +3927,11 @@ packages:
|
||||
resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
|
||||
dev: true
|
||||
|
||||
/glossy@0.1.7:
|
||||
resolution: {integrity: sha512-mTCC51QFadK75MvAhrL5nPVIP291NjML1guo10Sa7Yj04tJU4V++Vgm780NIddg9etQD9D8FM67hFGqM8EE2HQ==}
|
||||
engines: {node: '>= 0.2.5'}
|
||||
dev: false
|
||||
|
||||
/gopd@1.0.1:
|
||||
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
|
||||
dependencies:
|
||||
@ -7322,6 +7364,11 @@ packages:
|
||||
periscopic: 3.1.0
|
||||
dev: true
|
||||
|
||||
/syslog-parse@2.0.0:
|
||||
resolution: {integrity: sha512-FI6xGyKM9dRdNCrCWiEy1QhRZskDYkW+lUNAIXkFeht0/XCsSdZ7UsPANFLk0h8b+8Is6Ll8bllUNjME+XCANA==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
dev: false
|
||||
|
||||
/tail@2.2.6:
|
||||
resolution: {integrity: sha512-IQ6G4wK/t8VBauYiGPLx+d3fA5XjSVagjWV5SIYzvEvglbQjwEcukeYI68JOPpdydjxhZ9sIgzRlSmwSpphHyw==}
|
||||
engines: {node: '>= 6.0.0'}
|
||||
@ -7627,7 +7674,6 @@ packages:
|
||||
|
||||
/undici-types@5.26.5:
|
||||
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
|
||||
dev: true
|
||||
|
||||
/undici@5.26.5:
|
||||
resolution: {integrity: sha512-cSb4bPFd5qgR7qr2jYAi0hlX9n5YKK2ONKkLFkxl+v/9BvC0sOpZjBHDBSXc5lWAf5ty9oZdRXytBIHzgUcerw==}
|
||||
@ -7665,6 +7711,16 @@ packages:
|
||||
'@types/unist': 3.0.2
|
||||
dev: true
|
||||
|
||||
/unix-dgram@2.0.6:
|
||||
resolution: {integrity: sha512-AURroAsb73BZ6CdAyMrTk/hYKNj3DuYYEuOaB8bYMOHGKupRNScw90Q5C71tWJc3uE7dIeXRyuwN0xLLq3vDTg==}
|
||||
engines: {node: '>=0.10.48'}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
bindings: 1.5.0
|
||||
nan: 2.18.0
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/unpipe@1.0.0:
|
||||
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@ -7864,6 +7920,18 @@ packages:
|
||||
string-width: 5.1.2
|
||||
dev: true
|
||||
|
||||
/winston-syslog@2.7.0(winston@3.11.0):
|
||||
resolution: {integrity: sha512-w+V0lHO2W6XqcYlvVi4DrblwJShvQbAaruRvUlMPzH1Z+dYvUvo4ra2hhoF6UNTFmC9LBltcTG05ypYL6S/B8A==}
|
||||
engines: {node: '>= 8'}
|
||||
peerDependencies:
|
||||
winston: ^3.8.2
|
||||
dependencies:
|
||||
glossy: 0.1.7
|
||||
winston: 3.11.0
|
||||
optionalDependencies:
|
||||
unix-dgram: 2.0.6
|
||||
dev: false
|
||||
|
||||
/winston-transport@4.6.0:
|
||||
resolution: {integrity: sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
|
53
src/cli/edge-syslogd.ts
Normal file
53
src/cli/edge-syslogd.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import {
|
||||
DEBUG,
|
||||
DefaultSettingsService,
|
||||
SETTINGS,
|
||||
SYSLOGD_PORT,
|
||||
} from '$constants'
|
||||
import { InstanceLogger } from '$services'
|
||||
import { LogLevelName, LoggerService } from '$src/shared'
|
||||
import * as dgram from 'dgram'
|
||||
import parse from 'syslog-parse'
|
||||
|
||||
const server = dgram.createSocket('udp4')
|
||||
|
||||
DefaultSettingsService(SETTINGS)
|
||||
|
||||
const PORT = SYSLOGD_PORT()
|
||||
const HOST = '0.0.0.0'
|
||||
|
||||
const { dbg, info, error } = LoggerService({
|
||||
level: DEBUG() ? LogLevelName.Debug : LogLevelName.Info,
|
||||
}).create(`edge-syslogd`)
|
||||
|
||||
console.log(`debug is ${DEBUG()}`)
|
||||
|
||||
server.on('error', (err) => {
|
||||
console.log(`Server error:\n${err.stack}`)
|
||||
server.close()
|
||||
})
|
||||
|
||||
server.on('message', (msg, rinfo) => {
|
||||
const raw = msg.toString()
|
||||
const parsed = parse(raw)
|
||||
if (!parsed) {
|
||||
return
|
||||
}
|
||||
dbg(parsed)
|
||||
|
||||
const { process: instanceId, severity, message } = parsed
|
||||
|
||||
const logger = InstanceLogger(instanceId, `exec`)
|
||||
if (severity === 'info') {
|
||||
logger.info(message)
|
||||
} else {
|
||||
logger.error(message)
|
||||
}
|
||||
})
|
||||
|
||||
server.on('listening', () => {
|
||||
const address = server.address()
|
||||
console.log(`Server listening ${address.address}:${address.port}`)
|
||||
})
|
||||
|
||||
server.bind(PORT, HOST)
|
@ -98,6 +98,8 @@ export const SETTINGS = {
|
||||
TEST_EMAIL: mkString(),
|
||||
|
||||
LS_WEBHOOK_SECRET: mkString(''),
|
||||
|
||||
SYSLOGD_PORT: mkNumber(6514),
|
||||
}
|
||||
;(() => {
|
||||
let passed = true
|
||||
@ -221,6 +223,8 @@ export const TEST_EMAIL = () => settings().TEST_EMAIL
|
||||
|
||||
export const LS_WEBHOOK_SECRET = () => settings().LS_WEBHOOK_SECRET
|
||||
|
||||
export const SYSLOGD_PORT = () => settings().SYSLOGD_PORT
|
||||
|
||||
/** Helpers */
|
||||
|
||||
export const MOTHERSHIP_DATA_ROOT = () => INSTANCE_DATA_ROOT(MOTHERSHIP_NAME())
|
||||
|
@ -25,8 +25,8 @@ export function InstanceLogger(instanceId: string, target: string) {
|
||||
}
|
||||
|
||||
const logDirectory = mkInstanceDataPath(instanceId, `logs`)
|
||||
console.log(`Creating ${logDirectory}`)
|
||||
if (!fs.existsSync(logDirectory)) {
|
||||
console.log(`Creating ${logDirectory}`)
|
||||
fs.mkdirSync(logDirectory, { recursive: true })
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
import {
|
||||
APEX_DOMAIN,
|
||||
SYSLOGD_PORT,
|
||||
mkContainerHomePath,
|
||||
mkInstanceDataPath,
|
||||
} from '$constants'
|
||||
import { InstanceLogger, PortService } from '$services'
|
||||
import { PortService } from '$services'
|
||||
import {
|
||||
LoggerService,
|
||||
SingletonBaseConfig,
|
||||
@ -19,6 +20,7 @@ import MemoryStream from 'memorystream'
|
||||
import { gte } from 'semver'
|
||||
import { AsyncReturnType } from 'type-fest'
|
||||
import { PocketbaseReleaseVersionService } from '../PocketbaseReleaseVersionService'
|
||||
import { SyslogLogger } from '../SyslogService'
|
||||
|
||||
export type Env = { [_: string]: string }
|
||||
export type SpawnConfig = {
|
||||
@ -92,7 +94,7 @@ export const createPocketbaseService = async (
|
||||
} = _cfg
|
||||
|
||||
logger.breadcrumb(subdomain).breadcrumb(instanceId)
|
||||
const iLogger = InstanceLogger(instanceId, 'exec')
|
||||
const iLogger = SyslogLogger(instanceId, 'exec')
|
||||
|
||||
const _version = version || maxVersion // If _version is blank, we use the max version available
|
||||
const realVersion = await getVersion(_version)
|
||||
@ -106,20 +108,9 @@ export const createPocketbaseService = async (
|
||||
const docker = new Docker()
|
||||
iLogger.info(`Starting instance`)
|
||||
|
||||
const _stdoutData = (data: Buffer) => {
|
||||
const lines = data.toString().split(/\n/)
|
||||
lines.forEach((line) => {
|
||||
iLogger.info(line)
|
||||
})
|
||||
}
|
||||
const _stdoutData = (data: Buffer) => {}
|
||||
stdout.on('data', _stdoutData)
|
||||
const _stdErrData = (data: Buffer) => {
|
||||
const lines = data.toString().split(/\n/)
|
||||
lines.forEach((line) => {
|
||||
error(line)
|
||||
iLogger.error(line)
|
||||
})
|
||||
}
|
||||
const _stdErrData = (data: Buffer) => {}
|
||||
stderr.on('data', _stdErrData)
|
||||
const Binds = [
|
||||
`${mkInstanceDataPath(instanceId)}:${mkContainerHomePath()}`,
|
||||
@ -154,6 +145,13 @@ export const createPocketbaseService = async (
|
||||
Hard: 4096,
|
||||
},
|
||||
],
|
||||
LogConfig: {
|
||||
Type: 'syslog',
|
||||
Config: {
|
||||
'syslog-address': `udp://localhost:${SYSLOGD_PORT()}`,
|
||||
tag: instanceId,
|
||||
},
|
||||
},
|
||||
},
|
||||
Tty: false,
|
||||
ExposedPorts: {
|
||||
|
48
src/services/SyslogService/index.ts
Normal file
48
src/services/SyslogService/index.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { SYSLOGD_PORT } from '$constants'
|
||||
import { LoggerService } from '$shared'
|
||||
import * as winston from 'winston'
|
||||
import 'winston-syslog'
|
||||
|
||||
const loggers: {
|
||||
[key: string]: {
|
||||
info: (msg: string) => void
|
||||
error: (msg: string) => void
|
||||
}
|
||||
} = {}
|
||||
|
||||
export function SyslogLogger(instanceId: string, target: string) {
|
||||
const loggerKey = `${instanceId}_${target}`
|
||||
if (loggers[loggerKey]) {
|
||||
return loggers[loggerKey]!
|
||||
}
|
||||
|
||||
const logger = winston.createLogger({
|
||||
format: winston.format.printf((info) => {
|
||||
return info.message
|
||||
}),
|
||||
transports: [
|
||||
new winston.transports.Syslog({
|
||||
host: `localhost`,
|
||||
port: SYSLOGD_PORT(),
|
||||
app_name: instanceId,
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
const { error, warn } = LoggerService()
|
||||
.create('SyslogLogger')
|
||||
.breadcrumb(instanceId)
|
||||
.breadcrumb(target)
|
||||
|
||||
const api = {
|
||||
info: (msg: string) => {
|
||||
logger.info(msg)
|
||||
},
|
||||
error: (msg: string) => {
|
||||
logger.error(msg)
|
||||
},
|
||||
}
|
||||
|
||||
loggers[loggerKey] = api
|
||||
return api
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user