Skip to content

Commit e09bc02

Browse files
authored
feat: enhance logging with environment-based configuration (#530)
# Enhance logging system with environment-based configuration This PR improves the edge worker logging system by adding environment-based auto-configuration: - Added environment detection to automatically set appropriate log formats: - Local development: Uses 'fancy' format with colors and icons - Production: Uses 'simple' format with key=value pairs - Implemented smart defaults for log levels: - Local development: 'verbose' level for detailed logs - Production: 'info' level for standard operational logs - Added support for the NO_COLOR standard to disable colored output - Created explicit configuration overrides: - `EDGE_WORKER_LOG_FORMAT`: Override the auto-detected format ('fancy'|'simple') - `EDGE_WORKER_LOG_LEVEL`: Override the environment-based log level - Modified the SupabasePlatformAdapter to initialize the logging factory with environment variables - Added comprehensive tests for all new configuration options
1 parent 415fdd9 commit e09bc02

File tree

3 files changed

+143
-8
lines changed

3 files changed

+143
-8
lines changed

pkgs/edge-worker/src/platform/SupabasePlatformAdapter.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ export class SupabasePlatformAdapter implements PlatformAdapter<SupabaseResource
5050
private queries: Queries;
5151
private deps: SupabasePlatformDeps;
5252

53-
// Logging factory with dynamic workerId support
54-
private loggingFactory = createLoggingFactory();
53+
// Logging factory with dynamic workerId support (initialized in constructor)
54+
private loggingFactory!: ReturnType<typeof createLoggingFactory>;
5555

5656
constructor(
5757
options?: { sql?: Sql; connectionString?: string },
@@ -73,9 +73,9 @@ export class SupabasePlatformAdapter implements PlatformAdapter<SupabaseResource
7373
// Create abort controller for shutdown signal
7474
this.abortController = new AbortController();
7575

76-
// Set initial log level
77-
const logLevel = this.validatedEnv.EDGE_WORKER_LOG_LEVEL || 'info';
78-
this.loggingFactory.setLogLevel(logLevel);
76+
// Create logging factory with environment for auto-configuration
77+
// (log level, format, and colors are determined from env)
78+
this.loggingFactory = createLoggingFactory(env);
7979

8080
// startWorker logger with a default module name
8181
this.logger = this.loggingFactory.createLogger('SupabasePlatformAdapter');

pkgs/edge-worker/src/platform/logging.ts

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,38 @@
11
import type { Logger } from './types.js';
2+
import { isLocalSupabaseEnv } from '../shared/localDetection.js';
23

34
/**
4-
* Creates a logging factory with dynamic workerId support
5+
* Log format type: 'fancy' for local dev with colors/icons, 'simple' for hosted with key=value
56
*/
6-
export function createLoggingFactory() {
7+
export type LogFormat = 'fancy' | 'simple';
8+
9+
/**
10+
* Environment record type for logging configuration
11+
*/
12+
export type LoggingEnv = Record<string, string | undefined>;
13+
14+
/**
15+
* Creates a logging factory with dynamic workerId support and environment-based configuration
16+
* @param env - Optional environment variables for auto-configuration (NO_COLOR, EDGE_WORKER_LOG_FORMAT, etc.)
17+
*/
18+
export function createLoggingFactory(env?: LoggingEnv) {
19+
// Determine if colors should be enabled (NO_COLOR standard: any value disables colors)
20+
const colorsEnabled = env?.NO_COLOR === undefined;
21+
22+
// Determine if this is a local Supabase environment
23+
const isLocal = env ? isLocalSupabaseEnv(env) : false;
24+
25+
// Determine log format: explicit override > auto-detect from environment
26+
const explicitFormat = env?.EDGE_WORKER_LOG_FORMAT as LogFormat | undefined;
27+
const format: LogFormat = explicitFormat ?? (isLocal ? 'fancy' : 'simple');
28+
29+
// Determine log level: explicit override > environment-based default (local=verbose, hosted=info)
30+
const explicitLevel = env?.EDGE_WORKER_LOG_LEVEL;
31+
const defaultLevel = isLocal ? 'verbose' : 'info';
32+
let logLevel = explicitLevel ?? defaultLevel;
33+
734
// Shared state for all loggers
835
let sharedWorkerId = 'unknown';
9-
let logLevel = 'info';
1036

1137
// All created logger instances - using Map for efficient lookup
1238
const loggers: Map<string, Logger> = new Map();
@@ -101,5 +127,15 @@ export function createLoggingFactory() {
101127
createLogger,
102128
setWorkerId,
103129
setLogLevel,
130+
// Expose configuration for inspection/testing
131+
get colorsEnabled() {
132+
return colorsEnabled;
133+
},
134+
get format() {
135+
return format;
136+
},
137+
get logLevel() {
138+
return logLevel;
139+
},
104140
};
105141
}

pkgs/edge-worker/tests/unit/platform/logging.test.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,102 @@ Deno.test('createLoggingFactory - level hierarchy: error < warn < info < verbose
127127
restore();
128128
}
129129
});
130+
131+
// ============================================================
132+
// Environment Configuration Tests (Phase 2)
133+
// ============================================================
134+
135+
Deno.test('createLoggingFactory - colorsEnabled defaults to true', () => {
136+
const factory = createLoggingFactory();
137+
138+
assertEquals(factory.colorsEnabled, true);
139+
});
140+
141+
Deno.test('createLoggingFactory - colorsEnabled is false when NO_COLOR env var is set', () => {
142+
const factory = createLoggingFactory({ NO_COLOR: '1' });
143+
144+
assertEquals(factory.colorsEnabled, false);
145+
});
146+
147+
Deno.test('createLoggingFactory - colorsEnabled is false when NO_COLOR is any truthy value', () => {
148+
// NO_COLOR standard: presence of the variable (any value) disables colors
149+
const factory1 = createLoggingFactory({ NO_COLOR: 'true' });
150+
assertEquals(factory1.colorsEnabled, false);
151+
152+
const factory2 = createLoggingFactory({ NO_COLOR: '' });
153+
// Empty string is still "set" per NO_COLOR standard
154+
assertEquals(factory2.colorsEnabled, false);
155+
});
156+
157+
Deno.test('createLoggingFactory - format defaults to simple when env not provided', () => {
158+
const factory = createLoggingFactory();
159+
160+
assertEquals(factory.format, 'simple');
161+
});
162+
163+
Deno.test('createLoggingFactory - format is fancy for local Supabase environment', () => {
164+
const localEnv = {
165+
SUPABASE_ANON_KEY: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0',
166+
};
167+
const factory = createLoggingFactory(localEnv);
168+
169+
assertEquals(factory.format, 'fancy');
170+
});
171+
172+
Deno.test('createLoggingFactory - format is simple for hosted Supabase environment', () => {
173+
const hostedEnv = {
174+
SUPABASE_ANON_KEY: 'some-production-key',
175+
};
176+
const factory = createLoggingFactory(hostedEnv);
177+
178+
assertEquals(factory.format, 'simple');
179+
});
180+
181+
Deno.test('createLoggingFactory - EDGE_WORKER_LOG_FORMAT overrides auto-detection', () => {
182+
// Even in local env, explicit format override should win
183+
const localEnv = {
184+
SUPABASE_ANON_KEY: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0',
185+
EDGE_WORKER_LOG_FORMAT: 'simple',
186+
};
187+
const factory = createLoggingFactory(localEnv);
188+
189+
assertEquals(factory.format, 'simple');
190+
});
191+
192+
Deno.test('createLoggingFactory - EDGE_WORKER_LOG_FORMAT can set fancy in hosted env', () => {
193+
const hostedEnv = {
194+
SUPABASE_ANON_KEY: 'some-production-key',
195+
EDGE_WORKER_LOG_FORMAT: 'fancy',
196+
};
197+
const factory = createLoggingFactory(hostedEnv);
198+
199+
assertEquals(factory.format, 'fancy');
200+
});
201+
202+
Deno.test('createLoggingFactory - default log level is verbose for local env', () => {
203+
const localEnv = {
204+
SUPABASE_ANON_KEY: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0',
205+
};
206+
const factory = createLoggingFactory(localEnv);
207+
208+
assertEquals(factory.logLevel, 'verbose');
209+
});
210+
211+
Deno.test('createLoggingFactory - default log level is info for hosted env', () => {
212+
const hostedEnv = {
213+
SUPABASE_ANON_KEY: 'some-production-key',
214+
};
215+
const factory = createLoggingFactory(hostedEnv);
216+
217+
assertEquals(factory.logLevel, 'info');
218+
});
219+
220+
Deno.test('createLoggingFactory - EDGE_WORKER_LOG_LEVEL overrides default', () => {
221+
const localEnv = {
222+
SUPABASE_ANON_KEY: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0',
223+
EDGE_WORKER_LOG_LEVEL: 'debug',
224+
};
225+
const factory = createLoggingFactory(localEnv);
226+
227+
assertEquals(factory.logLevel, 'debug');
228+
});

0 commit comments

Comments
 (0)