Skip to content

Commit

Permalink
refactor: Decouple log manager from runtime settings and serverpod. (s…
Browse files Browse the repository at this point in the history
  • Loading branch information
Isakdl authored Jul 12, 2024
1 parent 846bdb0 commit 0a41375
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 125 deletions.
4 changes: 2 additions & 2 deletions packages/serverpod/lib/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ export 'src/server/future_call.dart';
export 'src/server/message_central.dart';
export 'src/server/run_mode.dart';
export 'src/server/server.dart';
export 'src/server/serverpod.dart';
export 'src/server/session.dart';
export 'src/server/serverpod.dart' hide ServerpodInternalMethods;
export 'src/server/session.dart' hide SessionInternalMethods;
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ class DatabaseConnection {
// Use the current stack trace if there is no exception.
trace ??= StackTrace.current;

session.serverpod.logManager.logQuery(
session.logManager.logQuery(
session,
query: query,
duration: duration,
Expand Down
4 changes: 1 addition & 3 deletions packages/serverpod/lib/src/endpoints/insights.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,7 @@ class InsightsEndpoint extends Endpoint {
/// Get the latest [numEntries] from the session log.
Future<SessionLogResult> getOpenSessionLog(
Session session, int? numEntries, SessionLogFilter? filter) async {
var logs = session.serverpod.logManager
.getOpenSessionLogs(numEntries ?? 100, filter);
return SessionLogResult(sessionLog: logs);
return SessionLogResult(sessionLog: []);
}

/// Retrieve information about the state of the caches on this server.
Expand Down
142 changes: 48 additions & 94 deletions packages/serverpod/lib/src/server/log_manager/log_manager.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dart:io';
import 'package:meta/meta.dart';
import 'package:serverpod/database.dart';
import 'package:serverpod/src/server/log_manager/log_settings.dart';
import 'package:serverpod/src/server/log_manager/log_writer.dart';
import 'package:synchronized/synchronized.dart';

Expand All @@ -10,56 +9,30 @@ import '../../generated/protocol.dart';

const double _microNormalizer = 1000 * 1000;

/// The [LogManager] handles logging and logging settings. Typically only used
/// internally by Serverpod.
class LogManager {
/// The [LogSettingsManager] the log manager retrieves its settings from.
final LogSettingsManager settings;

/// The [RuntimeSettings] the log manager retrieves its settings from.
@Deprecated('Will be removed in 3.0.0')
final RuntimeSettings runtimeSettings;
@internal
class SessionLogManager {
final String _serverId;

final LogWriter _logWriter;

final List<SessionLogEntryCache> _openSessionLogs = [];

final String _serverId;

int _nextTemporarySessionId = -1;

/// Returns a new unique temporary session id. The id will be negative, and
/// ids are only unique to this running instance.
int nextTemporarySessionId() {
var id = _nextTemporarySessionId;
_nextTemporarySessionId -= 1;
return id;
}
final LogSettings Function(Session) _settingsForSession;

/// Creates a new [LogManager] from [RuntimeSettings].
LogManager(
this.runtimeSettings,
@internal
SessionLogManager(
LogWriter logWriter, {
required LogSettings Function(Session) settingsForSession,
required String serverId,
}) : _logWriter = logWriter,
_serverId = serverId,
settings = LogSettingsManager(runtimeSettings);

/// Initializes the logging for a session, automatically called when a session
/// is created. Each call to this method should have a corresponding
/// [finalizeSessionLog] call.
SessionLogEntryCache initializeSessionLog(Session session) {
var logEntry = SessionLogEntryCache(session);
_openSessionLogs.add(logEntry);
return logEntry;
}
_settingsForSession = settingsForSession,
_serverId = serverId;

bool _shouldLogQuery({
required Session session,
required bool slow,
required bool failed,
}) {
var logSettings = settings.getLogSettingsForSession(session);
var logSettings = _settingsForSession(session);
if (logSettings.logAllQueries) {
return true;
}
Expand All @@ -76,7 +49,7 @@ class LogManager {
required Session session,
required LogEntry entry,
}) {
var logSettings = settings.getLogSettingsForSession(session);
var logSettings = _settingsForSession(session);
var serverLogLevel = (logSettings.logLevel);

return entry.logLevel.index >= serverLogLevel.index;
Expand All @@ -88,7 +61,7 @@ class LogManager {
required bool slow,
required bool failed,
}) {
var logSettings = settings.getLogSettingsForSession(session);
var logSettings = _settingsForSession(session);
if (logSettings.logAllSessions) {
return true;
}
Expand Down Expand Up @@ -164,7 +137,7 @@ class LogManager {
}) async {
var executionTime = duration.inMicroseconds / _microNormalizer;

var logSettings = settings.getLogSettingsForSession(session);
var logSettings = _settingsForSession(session);

var slow = executionTime >= logSettings.slowQueryDuration;
var shouldLog = _shouldLogQuery(
Expand Down Expand Up @@ -212,8 +185,8 @@ class LogManager {
}) async {
var executionTime = duration.inMicroseconds / _microNormalizer;

var slow = executionTime >=
settings.getLogSettingsForSession(session).slowSessionDuration;
var slow =
executionTime >= _settingsForSession(session).slowSessionDuration;

var shouldLog = _shouldLogMessage(
session: session,
Expand Down Expand Up @@ -292,7 +265,7 @@ class LogManager {

assert(session.sessionLogs.currentEndpoint != null);

var logSettings = settings.getLogSettingsForSession(session);
var logSettings = _settingsForSession(session);
if (!logSettings.logStreamingSessionsContinuously) {
// This call should not stream continuously.
return;
Expand Down Expand Up @@ -327,8 +300,6 @@ class LogManager {
String? exception,
StackTrace? stackTrace,
}) async {
_openSessionLogs.removeWhere((logEntry) => logEntry.session == session);

// If verbose logging is enabled, output otherwise unlogged exceptions to
// console.
if (exception != null && !session.enableLogging) {
Expand All @@ -344,7 +315,7 @@ class LogManager {
var cachedEntry = session.sessionLogs;
LogSettings? logSettings;
if (session is! StreamingSession) {
logSettings = settings.getLogSettingsForSession(session);
logSettings = _settingsForSession(session);
}

if (session.serverpod.runMode == ServerpodRunMode.development) {
Expand Down Expand Up @@ -424,57 +395,40 @@ class LogManager {
}
return null;
}
}

/// Returns a list of logs for all open sessions.
List<SessionLogInfo> getOpenSessionLogs(
int numEntries, SessionLogFilter? filter) {
var sessionLog = <SessionLogInfo>[];

var numFoundEntries = 0;
var i = 0;
while (i < _openSessionLogs.length && numFoundEntries < numEntries) {
var entry = _openSessionLogs[i];
i += 1;
numFoundEntries += 1;

// Check filter (ignore slow and errors as session is still open)
if (filter != null) {
var session = entry.session;
if (session is MethodCallSession) {
if (filter.endpoint != null &&
filter.endpoint != '' &&
session.endpointName != filter.endpoint) {
continue;
}
if (filter.endpoint != null &&
filter.endpoint != '' &&
filter.method != null &&
filter.method != '' &&
session.endpointName != filter.endpoint &&
session.methodName != filter.method) {
continue;
}
}
}
/// The [LogManager] handles logging and logging settings. Typically only used
/// internally by Serverpod.
class LogManager {
/// The [RuntimeSettings] the log manager retrieves its settings from.
@Deprecated('Will be removed in 3.0.0')
final RuntimeSettings runtimeSettings;

sessionLog.add(
SessionLogInfo(
sessionLogEntry: SessionLogEntry(
serverId: Serverpod.instance.serverId,
time: entry.session.startTime,
touched: DateTime.now(),
endpoint: _endpointForSession(entry.session),
method: _methodForSession(entry.session),
numQueries: entry.numQueries,
),
queries: entry.queries,
logs: entry.logEntries,
messages: entry.messages,
),
);
}
final List<SessionLogEntryCache> _openSessionLogs = [];

int _nextTemporarySessionId = -1;

return sessionLog;
/// Returns a new unique temporary session id. The id will be negative, and
/// ids are only unique to this running instance.
int nextTemporarySessionId() {
var id = _nextTemporarySessionId;
_nextTemporarySessionId -= 1;
return id;
}

/// Creates a new [LogManager] from [RuntimeSettings].
LogManager(
this.runtimeSettings, {
required String serverId,
});

/// Initializes the logging for a session, automatically called when a session
/// is created. Each call to this method should have a corresponding
/// [finalizeSessionLog] call.
SessionLogEntryCache initializeSessionLog(Session session) {
var logEntry = SessionLogEntryCache(session);
_openSessionLogs.add(logEntry);
return logEntry;
}
}

Expand Down
42 changes: 20 additions & 22 deletions packages/serverpod/lib/src/server/serverpod.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import 'package:serverpod/src/server/features.dart';
import 'package:serverpod/src/server/future_call_manager.dart';
import 'package:serverpod/src/server/health_check_manager.dart';
import 'package:serverpod/src/server/log_manager/log_manager.dart';
import 'package:serverpod/src/server/log_manager/log_writer.dart';
import 'package:serverpod/src/server/log_manager/log_settings.dart';
import 'package:serverpod_shared/serverpod_shared.dart';

import '../authentication/default_authentication_handler.dart';
Expand Down Expand Up @@ -143,13 +143,13 @@ class Serverpod {

late LogManager _logManager;

late LogWriter _logWriter;

/// The [LogManager] of the Serverpod, its typically only used internally
/// by the Serverpod. Instead of using this object directly, call the log
/// method on the current [Session].
LogManager get logManager => _logManager;

LogSettingsManager? _logSettingsManager;

FutureCallManager? _futureCallManager;

/// Cloud storages used by the serverpod. By default two storages are set up,
Expand Down Expand Up @@ -192,10 +192,15 @@ class Serverpod {
/// Serverpod runtime settings as read from the database.
internal.RuntimeSettings get runtimeSettings => _runtimeSettings!;

void _updateLogSettings(internal.RuntimeSettings settings) {
_runtimeSettings = settings;
_logSettingsManager = LogSettingsManager(settings);
_logManager = LogManager(settings, serverId: serverId);
}

/// Updates the runtime settings and writes the new settings to the database.
Future<void> updateRuntimeSettings(internal.RuntimeSettings settings) async {
_runtimeSettings = settings;
_logManager = LogManager(settings, _logWriter, serverId: serverId);
_updateLogSettings(settings);
if (Features.enablePersistentLogging) {
await _storeRuntimeSettings(settings);
}
Expand All @@ -214,8 +219,7 @@ class Serverpod {
try {
var settings = await internal.RuntimeSettings.db.findFirstRow(session);
if (settings != null) {
_runtimeSettings = settings;
_logManager = LogManager(settings, _logWriter, serverId: serverId);
_updateLogSettings(settings);
}
await session.close();
} catch (e, stackTrace) {
Expand Down Expand Up @@ -306,17 +310,9 @@ class Serverpod {
);
Features(this.config);

_logWriter = Features.enablePersistentLogging
? DatabaseLogWriter()
: StdOutLogWriter();

// Create a temporary log manager with default settings, until we have
// loaded settings from the database.
_logManager = LogManager(
_defaultRuntimeSettings,
_logWriter,
serverId: serverId,
);
_updateLogSettings(_defaultRuntimeSettings);

// Setup database
var databaseConfiguration = this.config.database;
Expand Down Expand Up @@ -440,12 +436,7 @@ class Serverpod {
_exitCode = 1;
}

// Setup log manager.
_logManager = LogManager(
_runtimeSettings ?? _defaultRuntimeSettings,
_logWriter,
serverId: serverId,
);
_updateLogSettings(_runtimeSettings ?? _defaultRuntimeSettings);

// Connect to Redis
if (Features.enableRedis) {
Expand Down Expand Up @@ -820,3 +811,10 @@ class Serverpod {
return secret != null && secret.isNotEmpty && secret.length > 20;
}
}

/// Internal methods used by the Serverpod. These methods are not intended to
/// be exposed to end users.
extension ServerpodInternalMethods on Serverpod {
/// Retrieve the log settings manager
LogSettingsManager get logSettingsManager => _logSettingsManager!;
}
Loading

0 comments on commit 0a41375

Please sign in to comment.