Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Core/CommonKit/Sources/CommonKit/Utils/Logger/Logger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <logs-folder>] [--port <port>] <folder>
USAGE: ./MockingStar start [--logs-folder <logs-folder>] [--port <port>] [--threshold <threshold>] <folder>

ARGUMENTS:
<folder> Mocks folder path
Expand All @@ -25,6 +25,8 @@ OPTIONS:
-l, --logs-folder <logs-folder>
Logs folder
-p, --port <port> HTTP Server Port (default: 8008)
-t, --threshold <threshold>
Warn if a mock response takes longer than this duration in seconds (default: 0.2)
-h, --help Show help information.
```

Expand Down
4 changes: 2 additions & 2 deletions MockingStarExecutable/Sources/HTTPServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
7 changes: 6 additions & 1 deletion MockingStarExecutable/Sources/MockingStar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,23 @@ 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

func run() async throws {
@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()
}
}
Expand Down
44 changes: 44 additions & 0 deletions MockingStarExecutable/Sources/TimedMockHandler.swift
Original file line number Diff line number Diff line change
@@ -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
}
}
Loading