unitup 0.0.2 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -277,19 +277,30 @@ unitup status api --raw
277
277
 
278
278
  ### `unitup logs <name>`
279
279
 
280
- Displays logs collected by systemd's `journalctl`.
280
+ View or stream systemd journalctl logs for a service.
281
281
 
282
282
  ```bash
283
283
  # View last 100 log lines (default)
284
- unitup logs api
284
+ unitup logs app
285
285
 
286
- # Specify number of lines
287
- unitup logs api --lines 30
286
+ # Stream logs in real-time
287
+ unitup logs app --follow
288
288
 
289
- # Live follow/stream mode
290
- unitup logs api --follow
289
+ # View last 50 lines of clean raw console output without systemd metadata prefix
290
+ unitup logs app -c --lines 50
291
+ # or
292
+ unitup logs app --cat --lines 50
293
+
294
+ # Specify custom journalctl output format
295
+ unitup logs app --output=json
291
296
  ```
292
297
 
298
+ **Options:**
299
+ - `-f`, `--follow`: Stream logs in real time.
300
+ - `-n`, `--lines <N>`: Specify number of log lines to show (default: 100).
301
+ - `-c`, `--cat`: Format log output cleanly without systemd timestamp/hostname metadata prefix (`journalctl -o cat`).
302
+ - `--output <format>`: Custom journalctl output mode (e.g. `cat`, `short`, `json`).
303
+
293
304
  ---
294
305
 
295
306
  ### `unitup list`
package/bin/unitup.js CHANGED
File without changes
package/index.d.ts CHANGED
@@ -72,6 +72,17 @@ export interface LogOptions {
72
72
  * @default 100
73
73
  */
74
74
  lines?: number;
75
+
76
+ /**
77
+ * Raw unformatted console output (-o cat) without systemd metadata prefix.
78
+ * @default false
79
+ */
80
+ cat?: boolean;
81
+
82
+ /**
83
+ * Journalctl output mode (e.g. 'cat', 'short', 'json').
84
+ */
85
+ output?: string;
75
86
  }
76
87
 
77
88
  /**
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "unitup",
3
- "version": "0.0.2",
3
+ "version": "0.0.6",
4
4
  "description": "Minimal systemd user service wrapper for Node.js scripts",
5
5
  "main": "src/index.js",
6
6
  "types": "./index.d.ts",
7
7
  "type": "module",
8
8
  "bin": {
9
- "unitup": "./bin/unitup.js"
9
+ "unitup": "bin/unitup.js"
10
10
  },
11
11
  "scripts": {
12
12
  "test": "node --test test/*.test.js"
package/src/cli.js CHANGED
@@ -38,6 +38,8 @@ export function parseArgs(argv) {
38
38
  enable: false,
39
39
  raw: false,
40
40
  follow: false,
41
+ cat: false,
42
+ output: '',
41
43
  lines: 100,
42
44
  help: false,
43
45
  version: false
@@ -114,6 +116,15 @@ export function parseArgs(argv) {
114
116
  } else if (arg === '-f' || arg === '--follow') {
115
117
  result.flags.follow = true;
116
118
  i++;
119
+ } else if (arg === '-c' || arg === '--cat') {
120
+ result.flags.cat = true;
121
+ i++;
122
+ } else if (arg === '--output') {
123
+ result.flags.output = argv[i + 1] || '';
124
+ i += 2;
125
+ } else if (arg.startsWith('--output=')) {
126
+ result.flags.output = arg.slice(9);
127
+ i++;
117
128
  } else if (!arg.startsWith('-')) {
118
129
  if (!result.command) {
119
130
  result.command = arg;
@@ -308,7 +319,9 @@ export async function runCli(argv = process.argv.slice(2)) {
308
319
  }
309
320
  const output = await runJournalctlLogs(name, {
310
321
  follow: flags.follow,
311
- lines: flags.lines
322
+ lines: flags.lines,
323
+ cat: flags.cat,
324
+ output: flags.output
312
325
  });
313
326
  if (typeof output === 'string') {
314
327
  console.log(output);
package/src/systemd.js CHANGED
@@ -480,27 +480,41 @@ export async function runJournalctlLogs(name, opts = {}) {
480
480
  const safeName = sanitizeServiceName(name);
481
481
  const unitFilename = getUnitFilename(safeName);
482
482
 
483
- const args = ['--user', '-u', unitFilename];
483
+ const baseArgs = ['-u', unitFilename];
484
484
 
485
- if (opts.follow) {
486
- args.push('-f');
487
- } else {
488
- args.push('--no-pager');
489
- const lines = opts.lines ? String(opts.lines) : '100';
490
- args.push('-n', lines);
485
+ if (opts.cat || opts.output === 'cat') {
486
+ baseArgs.push('-o', 'cat');
487
+ } else if (opts.output) {
488
+ baseArgs.push('-o', opts.output);
491
489
  }
492
490
 
493
491
  if (opts.follow) {
494
- // Spawn stream for follow mode
492
+ baseArgs.push('-f');
495
493
  try {
496
- const child = spawn('journalctl', args, { stdio: 'inherit', shell: false });
494
+ const child = spawn('journalctl', ['--user', ...baseArgs], { stdio: 'inherit', shell: false });
497
495
  child.on('error', () => {});
498
496
  return child;
499
497
  } catch {
500
498
  return null;
501
499
  }
502
500
  } else {
503
- const res = await runCommand('journalctl', args);
504
- return res.stdout || res.stderr || 'No logs found.';
501
+ baseArgs.push('--no-pager');
502
+ const lines = opts.lines ? String(opts.lines) : '100';
503
+ baseArgs.push('-n', lines);
504
+
505
+ // Try --user mode first
506
+ const userRes = await runCommand('journalctl', ['--user', ...baseArgs]);
507
+ const userOut = userRes.stdout || userRes.stderr || '';
508
+
509
+ // If user journal files do not exist or returned no entries, fallback to system journal
510
+ if (!userOut || userOut.includes('No journal files') || userOut.includes('No entries') || userRes.code !== 0) {
511
+ const sysRes = await runCommand('journalctl', baseArgs);
512
+ const sysOut = sysRes.stdout || sysRes.stderr || '';
513
+ if (sysOut && !sysOut.includes('No journal files')) {
514
+ return sysOut;
515
+ }
516
+ }
517
+
518
+ return userOut || 'No logs found.';
505
519
  }
506
520
  }
package/src/unit.js CHANGED
@@ -84,6 +84,7 @@ export function generateUnitContent(opts) {
84
84
  '',
85
85
  '[Service]',
86
86
  'Type=simple',
87
+ `SyslogIdentifier=unitup-${safeName}`,
87
88
  `WorkingDirectory=${cwd}`,
88
89
  `ExecStart=${execStartLine}`,
89
90
  `Restart=${restartPolicy}`,