From f950ebf04b0862b0fb1ce286767bc94ae332cf41 Mon Sep 17 00:00:00 2001 From: mbasakkarahan Date: Thu, 3 Sep 2026 11:50:35 +0300 Subject: [PATCH] Add logs for response time --- .../CommonKit/Utils/Logger/Logger.swift | 4 ++ .../GettingStarted/MockingStarCLI.md | 4 +- .../Sources/HTTPServer.swift | 4 +- .../Sources/MockingStar.swift | 7 ++- .../Sources/TimedMockHandler.swift | 44 +++++++++++++++++++ 5 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 MockingStarExecutable/Sources/TimedMockHandler.swift diff --git a/Core/CommonKit/Sources/CommonKit/Utils/Logger/Logger.swift b/Core/CommonKit/Sources/CommonKit/Utils/Logger/Logger.swift index b9ca67cac4..ec1033882a 100644 --- a/Core/CommonKit/Sources/CommonKit/Utils/Logger/Logger.swift +++ b/Core/CommonKit/Sources/CommonKit/Utils/Logger/Logger.swift @@ -12,6 +12,7 @@ extension Logger { public enum Constant { static let subsystem = "com.trendyol.MockingStar" public static var customLogFolderPath: String = "" + public static var enableConsoleLogging: Bool = false } } @@ -65,6 +66,9 @@ public final class Logger { #if DEBUG logHandlers.append(OSLogHandler(category: category)) #endif + if Constant.enableConsoleLogging { + logHandlers.append(ConsoleLogHandler()) + } #else logHandlers.append(ConsoleLogHandler()) #endif diff --git a/MockingStar/MockingStar/Documentation.docc/GettingStarted/MockingStarCLI.md b/MockingStar/MockingStar/Documentation.docc/GettingStarted/MockingStarCLI.md index 63d819dd23..85ed2629d4 100644 --- a/MockingStar/MockingStar/Documentation.docc/GettingStarted/MockingStarCLI.md +++ b/MockingStar/MockingStar/Documentation.docc/GettingStarted/MockingStarCLI.md @@ -16,7 +16,7 @@ You can use all operations independently of the UI with the Mocking Star CLI. Fe YusufOzgul@macOS Debug % ./MockingStar help start OVERVIEW: Start mock server -USAGE: ./MockingStar start [--logs-folder ] [--port ] +USAGE: ./MockingStar start [--logs-folder ] [--port ] [--threshold ] ARGUMENTS: Mocks folder path @@ -25,6 +25,8 @@ OPTIONS: -l, --logs-folder Logs folder -p, --port HTTP Server Port (default: 8008) + -t, --threshold + Warn if a mock response takes longer than this duration in seconds (default: 0.2) -h, --help Show help information. ``` diff --git a/MockingStarExecutable/Sources/HTTPServer.swift b/MockingStarExecutable/Sources/HTTPServer.swift index e815403fed..6c0e7556a8 100644 --- a/MockingStarExecutable/Sources/HTTPServer.swift +++ b/MockingStarExecutable/Sources/HTTPServer.swift @@ -12,11 +12,11 @@ import MockingStarCore final class HTTPServer { private let server: ServerInterface - init(port: UInt16) { + init(port: UInt16, threshold: Double = 0.2) { server = Server(port: port) let mockingStarCore = MockingStarCore() - server.registerMockHandler(mockingStarCore) + server.registerMockHandler(TimedMockHandler(wrapping: mockingStarCore, threshold: threshold)) server.registerMockSearchHandler(mockingStarCore) server.registerScenarioHandler(mockingStarCore) } diff --git a/MockingStarExecutable/Sources/MockingStar.swift b/MockingStarExecutable/Sources/MockingStar.swift index 8db572a790..721453eac1 100644 --- a/MockingStarExecutable/Sources/MockingStar.swift +++ b/MockingStarExecutable/Sources/MockingStar.swift @@ -28,6 +28,9 @@ private struct Start: AsyncParsableCommand { @Option(name: .shortAndLong, help: "HTTP Server Port") var port: UInt16 = 8008 + @Option(name: .shortAndLong, help: "Warn if a mock response takes longer than this duration in seconds") + var threshold: Double = 0.2 + @Argument(help: "Mocks folder path") var folder: String @@ -35,11 +38,13 @@ private struct Start: AsyncParsableCommand { @UserDefaultStorage("workspaces") var workspaces: [Workspace] = [] workspaces = [Workspace(name: "Workspace", path: folder, bookmark: Data())] + Logger.Constant.enableConsoleLogging = true + if let logsFolder, !logsFolder.isEmpty { Logger.Constant.customLogFolderPath = logsFolder } - let server = HTTPServer(port: port) + let server = HTTPServer(port: port, threshold: threshold) try await server.startServer() } } diff --git a/MockingStarExecutable/Sources/TimedMockHandler.swift b/MockingStarExecutable/Sources/TimedMockHandler.swift new file mode 100644 index 0000000000..0b57945ef7 --- /dev/null +++ b/MockingStarExecutable/Sources/TimedMockHandler.swift @@ -0,0 +1,44 @@ +// +// TimedMockHandler.swift +// +// +// Created by Maide Başak Karahan on 3.09.2026. +// + +import CommonKit +import Foundation +import Server + +final class TimedMockHandler: ServerMockHandlerInterface { + private let wrapped: ServerMockHandlerInterface + private let threshold: Double + private let logger = Logger(category: "CLI") + private let clock = ContinuousClock() + + init(wrapping wrapped: ServerMockHandlerInterface, threshold: Double) { + self.wrapped = wrapped + self.threshold = threshold + } + + func handle(url: URL, method: String, headers: [String: String], body: Data?, rawFlags: [String: String]) async throws -> (status: Int, body: Data, headers: [String: String]) { + let start = clock.now + let result = try await wrapped.handle(url: url, method: method, headers: headers, body: body, rawFlags: rawFlags) + let duration = clock.now - start + let durationSeconds = duration.seconds + + if durationSeconds > threshold { + let durationText = String(format: "%.2f", durationSeconds) + let thresholdText = String(format: "%.2f", threshold) + logger.warning("Mock response exceeded threshold: \(durationText)s (threshold: \(thresholdText)s) \(method) \(url.absoluteString)") + } + + return result + } +} + +private extension Duration { + var seconds: Double { + let components = self.components + return Double(components.seconds) + Double(components.attoseconds) / 1e18 + } +}