log-parse.test.ts 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import { describe, it, expect } from 'vitest';
  2. import { parseLogLine } from '@/pages/index/logParse';
  3. // Fixtures are real lines captured from `journalctl -u x-ui` on a production
  4. // host (the SysLog view) plus the in-memory app-log format. Each journald entry
  5. // carries a "Mon DD HH:MM:SS host ident[pid]: " prefix that the viewer used to
  6. // mistake for the level, leaving only a bare timestamp on screen.
  7. describe('parseLogLine — SysLog (journalctl) formats', () => {
  8. it('x-ui go-logging line: keeps level, strips prefix, tags X-UI', () => {
  9. const r = parseLogLine(
  10. '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',
  11. );
  12. expect(r.stamp).toBe('Jun 08 23:57:28');
  13. expect(r.levelText).toBe('INFO');
  14. expect(r.service).toBe('X-UI:');
  15. expect(r.body).toBe('mtproto: started mtg for inbound 3 on 0.0.0.0:8443');
  16. });
  17. it('xray go-logging line: lifts the XRAY service tag', () => {
  18. const r = parseLogLine(
  19. 'Jun 08 23:56:52 ubuntu-4gb-fsn1-1 /usr/local/x-ui/x-ui[72297]: WARNING - XRAY: core: Xray 26.6.1 started',
  20. );
  21. expect(r.stamp).toBe('Jun 08 23:56:52');
  22. expect(r.levelText).toBe('WARNING');
  23. expect(r.service).toBe('XRAY:');
  24. expect(r.body).toBe('core: Xray 26.6.1 started');
  25. });
  26. it('Go std-log line: strips the redundant embedded date, keeps the message', () => {
  27. const r = parseLogLine(
  28. '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',
  29. );
  30. expect(r.stamp).toBe('Jun 08 19:22:22');
  31. expect(r.levelText).toBe('');
  32. expect(r.body).toBe('http: TLS handshake error from 18.97.5.1:36022: EOF');
  33. });
  34. it('telego bracketed line: lifts the ERROR level out of "[ts] ERROR ..."', () => {
  35. const r = parseLogLine(
  36. '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...',
  37. );
  38. expect(r.stamp).toBe('Jun 09 00:14:52');
  39. expect(r.levelText).toBe('ERROR');
  40. expect(r.body).toBe('Retrying getting updates in 8s...');
  41. });
  42. it('systemd line: shows the body rather than a bare timestamp', () => {
  43. const r = parseLogLine(
  44. 'Jun 08 23:56:47 ubuntu-4gb-fsn1-1 systemd[1]: Stopping x-ui.service - x-ui Service...',
  45. );
  46. expect(r.stamp).toBe('Jun 08 23:56:47');
  47. expect(r.body).toBe('Stopping x-ui.service - x-ui Service...');
  48. });
  49. it('never collapses a journald entry to just its timestamp', () => {
  50. const r = parseLogLine(
  51. '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"',
  52. );
  53. expect(r.body.length).toBeGreaterThan(0);
  54. expect(r.body).toContain('Conflict');
  55. });
  56. });
  57. describe('parseLogLine — app-log format (SysLog off)', () => {
  58. it('parses "YYYY/MM/DD HH:MM:SS LEVEL - body"', () => {
  59. const r = parseLogLine('2026/06/09 00:35:09 INFO - mtproto: started mtg for inbound 3 on 0.0.0.0:8443');
  60. expect(r.date).toBe('2026/06/09');
  61. expect(r.time).toBe('00:35:09');
  62. expect(r.levelText).toBe('INFO');
  63. expect(r.service).toBe('X-UI:');
  64. expect(r.body).toBe('mtproto: started mtg for inbound 3 on 0.0.0.0:8443');
  65. });
  66. it('handles an empty line without throwing', () => {
  67. const r = parseLogLine('');
  68. expect(r.stamp).toBe('');
  69. expect(r.body).toBe('');
  70. });
  71. });