|
|
@@ -0,0 +1,80 @@
|
|
|
+import { describe, it, expect } from 'vitest';
|
|
|
+
|
|
|
+import { parseLogLine } from '@/pages/index/logParse';
|
|
|
+
|
|
|
+// Fixtures are real lines captured from `journalctl -u x-ui` on a production
|
|
|
+// host (the SysLog view) plus the in-memory app-log format. Each journald entry
|
|
|
+// carries a "Mon DD HH:MM:SS host ident[pid]: " prefix that the viewer used to
|
|
|
+// mistake for the level, leaving only a bare timestamp on screen.
|
|
|
+describe('parseLogLine — SysLog (journalctl) formats', () => {
|
|
|
+ it('x-ui go-logging line: keeps level, strips prefix, tags X-UI', () => {
|
|
|
+ const r = parseLogLine(
|
|
|
+ 'Jun 08 23:57:28 ubuntu-4gb-fsn1-1 /usr/local/x-ui/x-ui[72297]: INFO - mtproto: started mtg for inbound 3 on 0.0.0.0:8443',
|
|
|
+ );
|
|
|
+ expect(r.stamp).toBe('Jun 08 23:57:28');
|
|
|
+ expect(r.levelText).toBe('INFO');
|
|
|
+ expect(r.service).toBe('X-UI:');
|
|
|
+ expect(r.body).toBe('mtproto: started mtg for inbound 3 on 0.0.0.0:8443');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('xray go-logging line: lifts the XRAY service tag', () => {
|
|
|
+ const r = parseLogLine(
|
|
|
+ 'Jun 08 23:56:52 ubuntu-4gb-fsn1-1 /usr/local/x-ui/x-ui[72297]: WARNING - XRAY: core: Xray 26.6.1 started',
|
|
|
+ );
|
|
|
+ expect(r.stamp).toBe('Jun 08 23:56:52');
|
|
|
+ expect(r.levelText).toBe('WARNING');
|
|
|
+ expect(r.service).toBe('XRAY:');
|
|
|
+ expect(r.body).toBe('core: Xray 26.6.1 started');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('Go std-log line: strips the redundant embedded date, keeps the message', () => {
|
|
|
+ const r = parseLogLine(
|
|
|
+ 'Jun 08 19:22:22 ubuntu-4gb-fsn1-1 x-ui[1439]: 2026/06/08 19:22:22 http: TLS handshake error from 18.97.5.1:36022: EOF',
|
|
|
+ );
|
|
|
+ expect(r.stamp).toBe('Jun 08 19:22:22');
|
|
|
+ expect(r.levelText).toBe('');
|
|
|
+ expect(r.body).toBe('http: TLS handshake error from 18.97.5.1:36022: EOF');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('telego bracketed line: lifts the ERROR level out of "[ts] ERROR ..."', () => {
|
|
|
+ const r = parseLogLine(
|
|
|
+ 'Jun 09 00:14:52 ubuntu-4gb-fsn1-1 x-ui[72297]: [Tue Jun 9 00:14:52 UTC 2026] ERROR Retrying getting updates in 8s...',
|
|
|
+ );
|
|
|
+ expect(r.stamp).toBe('Jun 09 00:14:52');
|
|
|
+ expect(r.levelText).toBe('ERROR');
|
|
|
+ expect(r.body).toBe('Retrying getting updates in 8s...');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('systemd line: shows the body rather than a bare timestamp', () => {
|
|
|
+ const r = parseLogLine(
|
|
|
+ 'Jun 08 23:56:47 ubuntu-4gb-fsn1-1 systemd[1]: Stopping x-ui.service - x-ui Service...',
|
|
|
+ );
|
|
|
+ expect(r.stamp).toBe('Jun 08 23:56:47');
|
|
|
+ expect(r.body).toBe('Stopping x-ui.service - x-ui Service...');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('never collapses a journald entry to just its timestamp', () => {
|
|
|
+ const r = parseLogLine(
|
|
|
+ 'Jun 09 00:15:00 ubuntu-4gb-fsn1-1 x-ui[72297]: [Tue Jun 9 00:15:00 UTC 2026] ERROR Getting updates: telego: getUpdates: api: 409 "Conflict"',
|
|
|
+ );
|
|
|
+ expect(r.body.length).toBeGreaterThan(0);
|
|
|
+ expect(r.body).toContain('Conflict');
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+describe('parseLogLine — app-log format (SysLog off)', () => {
|
|
|
+ it('parses "YYYY/MM/DD HH:MM:SS LEVEL - body"', () => {
|
|
|
+ const r = parseLogLine('2026/06/09 00:35:09 INFO - mtproto: started mtg for inbound 3 on 0.0.0.0:8443');
|
|
|
+ expect(r.date).toBe('2026/06/09');
|
|
|
+ expect(r.time).toBe('00:35:09');
|
|
|
+ expect(r.levelText).toBe('INFO');
|
|
|
+ expect(r.service).toBe('X-UI:');
|
|
|
+ expect(r.body).toBe('mtproto: started mtg for inbound 3 on 0.0.0.0:8443');
|
|
|
+ });
|
|
|
+
|
|
|
+ it('handles an empty line without throwing', () => {
|
|
|
+ const r = parseLogLine('');
|
|
|
+ expect(r.stamp).toBe('');
|
|
|
+ expect(r.body).toBe('');
|
|
|
+ });
|
|
|
+});
|