Skip to content

Commit 1fee720

Browse files
committed
feat(logging): refactor logging system to use a centralized file logger and remove old logger implementations
1 parent ff36ebc commit 1fee720

19 files changed

Lines changed: 159 additions & 114 deletions

src/logging/file-logger.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/**
2+
* File Logger Adapter
3+
*
4+
* Implements the Logger interface writing to a local file.
5+
* This is the adapter layer - contains actual I/O operations.
6+
*/
7+
8+
import { homedir } from 'node:os';
9+
import { appendFileSync } from 'node:fs';
10+
import { join } from 'node:path';
11+
import type { Logger, LogCategory } from '../types/index.js';
12+
13+
const LOG_PREFIX = '[opencode-sync]';
14+
const LOG_DIR = join(homedir(), '.local/share/opencode/log');
15+
const LOG_FILE = join(LOG_DIR, 'opencode-sync.log');
16+
17+
/** Format a log message with timestamp and optional category */
18+
function formatMessage(message: string, category?: LogCategory): string {
19+
const timestamp = new Date().toISOString();
20+
const categoryTag = category ? `[${category}] ` : '';
21+
return `${timestamp} ${LOG_PREFIX} ${categoryTag}${message}`;
22+
}
23+
24+
/** Write a message to the log file */
25+
function writeToFile(message: string): void {
26+
try {
27+
appendFileSync(LOG_FILE, message + '\n');
28+
} catch {
29+
// Fallback to console if file write fails
30+
console.error(message);
31+
}
32+
}
33+
34+
/** File-based logger implementation */
35+
export const fileLogger: Logger = {
36+
log(message: string, category?: LogCategory): void {
37+
writeToFile(formatMessage(message, category));
38+
},
39+
40+
debug(message: string, category?: LogCategory): void {
41+
writeToFile(formatMessage(`[DEBUG] ${message}`, category));
42+
},
43+
44+
info(message: string, category?: LogCategory): void {
45+
writeToFile(formatMessage(`[INFO] ${message}`, category));
46+
},
47+
48+
warn(message: string, category?: LogCategory): void {
49+
writeToFile(formatMessage(`[WARN] ${message}`, category));
50+
},
51+
52+
error(message: string, category?: LogCategory): void {
53+
writeToFile(formatMessage(`[ERROR] ${message}`, category));
54+
},
55+
56+
startOperation(name: string): (result?: string) => void {
57+
const start = Date.now();
58+
writeToFile(formatMessage(`Starting: ${name}`, 'SYNC'));
59+
return (result?: string): void => {
60+
const duration = Date.now() - start;
61+
const suffix = result ? ` - ${result}` : '';
62+
writeToFile(formatMessage(`Completed: ${name} (${String(duration)}ms)${suffix}`, 'SYNC'));
63+
};
64+
},
65+
};
66+
67+
/**
68+
* Convenience exports for direct use (backwards compatibility).
69+
* Prefer injecting the Logger interface when possible.
70+
*/
71+
export function log(message: string, category?: LogCategory): void {
72+
fileLogger.log(message, category);
73+
}
74+
75+
export function syncLog(message: string): void {
76+
fileLogger.log(message, 'SYNC');
77+
}
78+
79+
export function logProgress(message: string): void {
80+
fileLogger.log(message, 'REPO');
81+
}
82+
83+
export function syncDebug(message: string): void {
84+
fileLogger.debug(message, 'SYNC');
85+
}
86+
87+
export function startOperation(name: string): (result?: string) => void {
88+
return fileLogger.startOperation(name);
89+
}
90+
91+
/** Log setup instructions when configuration is missing */
92+
export function logSetupInstructions(): void {
93+
log('To configure, either:', 'PLUGIN');
94+
log(' 1. Set GITHUB_TOKEN environment variable (with repo scope)', 'PLUGIN');
95+
log(' 2. Create ~/.config/opencode/opencode-sync.json with token', 'PLUGIN');
96+
}

src/logging/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Logging Module
3+
*
4+
* Exports the logger adapter and convenience functions.
5+
*/
6+
7+
export {
8+
fileLogger,
9+
log,
10+
syncLog,
11+
logProgress,
12+
syncDebug,
13+
startOperation,
14+
logSetupInstructions,
15+
} from './file-logger.js';

src/plugin/background-sync.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ import {
1313
deleteTombstonedItems,
1414
} from '../data/index.js';
1515
import { FileWatcher } from '../sync/watcher/index.js';
16-
import { syncLog } from '../sync/engine/logger.js';
16+
import { syncLog, log } from '../logging/index.js';
1717
import { getPluginState } from './state-manager.js';
18-
import { log } from './logger.js';
1918

2019
/** Active file watcher instance */
2120
let activeWatcher: FileWatcher | null = null;

src/plugin/logger.ts

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/plugin/plugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
import { getTokenSource, loadLocalData } from '../data/index.js';
1818
import { RepoStorageBackend } from '../storage/index.js';
1919
import type { PluginState } from './types.js';
20-
import { log, logSetupInstructions } from './logger.js';
20+
import { log, logSetupInstructions } from '../logging/index.js';
2121
import { getGitHubUsername, repoExists, createRepo } from './github-api.js';
2222
import {
2323
writePulledData,

src/plugin/sync-handler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
deleteTombstonedItems,
1515
} from '../data/index.js';
1616
import { getPluginState } from './state-manager.js';
17-
import { syncLog } from '../sync/engine/logger.js';
17+
import { syncLog } from '../logging/index.js';
1818

1919
type LogLevel = 'error' | 'info' | 'debug' | 'warn';
2020

src/storage/repo/graphql-client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import { fetchWithRetry } from './fetch.js';
66
import { GRAPHQL_BATCH_SIZE } from './constants.js';
77
import type { GraphQLRepositoryResponse, TruncatedFile } from './types.js';
8-
import { logProgress } from './logger.js';
8+
import { logProgress } from '../../logging/index.js';
99
import { buildBatchQuery, parseGraphQLResponse } from './graphql-query.js';
1010

1111
/** GraphQL client configuration */

src/storage/repo/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ export {
1515
export { GitHubHttpClient } from './http-client.js';
1616
export { GitOperations } from './git-operations.js';
1717
export { GraphQLClient } from './graphql-client.js';
18-
export { logProgress } from './logger.js';
18+
export { logProgress } from '../../logging/index.js';
1919
export * from './constants.js';
2020
export type * from './types.js';

src/storage/repo/logger.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/storage/repo/repo-client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type { StorageBackend, StorageFile } from '../interface.js';
99
import { SYNC_DIR, DEFAULT_MAX_RETRIES, DEFAULT_RETRY_DELAY_MS } from './constants.js';
1010
import { GitOperations } from './git-operations.js';
1111
import { GraphQLClient } from './graphql-client.js';
12-
import { logProgress } from './logger.js';
12+
import { logProgress } from '../../logging/index.js';
1313
import type { RepoClientConfig, GitTreeEntry } from './types.js';
1414

1515
// Re-export for backward compatibility

0 commit comments

Comments
 (0)