Skip to content

Commit 7c9662d

Browse files
authored
Add logging to the new ConnectionPool (#428)
1 parent b0180d1 commit 7c9662d

File tree

5 files changed

+60
-20
lines changed

5 files changed

+60
-20
lines changed

Diff for: Sources/AsyncHTTPClient/ConnectionPool.swift

+14-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ final class ConnectionPool {
124124
/// A key is initialized from a `URL`, it uses the components to derive a hashed value
125125
/// used by the `providers` dictionary to allow retrieving and creating
126126
/// connection providers associated to a certain request in constant time.
127-
struct Key: Hashable {
127+
struct Key: Hashable, CustomStringConvertible {
128128
init(_ request: HTTPClient.Request) {
129129
switch request.scheme {
130130
case "http":
@@ -179,6 +179,19 @@ final class ConnectionPool {
179179
}
180180
return config
181181
}
182+
183+
var description: String {
184+
var hasher = Hasher()
185+
self.tlsConfiguration?.hash(into: &hasher)
186+
let hash = hasher.finalize()
187+
var path = ""
188+
if self.unixPath != "" {
189+
path = self.unixPath
190+
} else {
191+
path = "\(self.host):\(self.port)"
192+
}
193+
return "\(self.scheme)://\(path) TLS-hash: \(hash)"
194+
}
182195
}
183196
}
184197

Diff for: Sources/AsyncHTTPClient/ConnectionPool/HTTP1.1/HTTP1ClientChannelHandler.swift

+5-9
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
3636
if let newRequest = self.request {
3737
var requestLogger = newRequest.logger
3838
requestLogger[metadataKey: "ahc-connection-id"] = "\(self.connection.id)"
39+
requestLogger[metadataKey: "ahc-el"] = "\(self.connection.channel.eventLoop)"
3940
self.logger = requestLogger
4041

4142
if let idleReadTimeout = newRequest.idleReadTimeout {
@@ -120,15 +121,15 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
120121
}
121122

122123
func channelReadComplete(context: ChannelHandlerContext) {
123-
self.logger.trace("Read complete caught")
124+
self.logger.trace("Channel read complete caught")
124125

125126
let action = self.state.channelReadComplete()
126127
self.run(action, context: context)
127128
}
128129

129130
func errorCaught(context: ChannelHandlerContext, error: Error) {
130-
self.logger.trace("Error caught", metadata: [
131-
"error": "\(error)",
131+
self.logger.trace("Channel error caught", metadata: [
132+
"ahc-error": "\(error)",
132133
])
133134

134135
let action = self.state.errorHappened(error)
@@ -142,12 +143,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
142143
let req = self.unwrapOutboundIn(data)
143144
self.request = req
144145

145-
self.logger.trace("New request to execute")
146-
147-
if let idleReadTimeout = self.request?.idleReadTimeout {
148-
self.idleReadTimeoutStateMachine = .init(timeAmount: idleReadTimeout)
149-
}
150-
146+
self.logger.debug("Request was scheduled on connection")
151147
req.willExecuteRequest(self)
152148

153149
let action = self.state.runNewRequest(head: req.requestHead, metadata: req.requestFramingMetadata)

Diff for: Sources/AsyncHTTPClient/ConnectionPool/HTTPConnectionPool+Factory.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ extension HTTPConnectionPool.ConnectionFactory {
6565
logger: Logger
6666
) {
6767
var logger = logger
68-
logger[metadataKey: "ahc-connection"] = "\(connectionID)"
68+
logger[metadataKey: "ahc-connection-id"] = "\(connectionID)"
6969

7070
self.makeChannel(connectionID: connectionID, deadline: deadline, eventLoop: eventLoop, logger: logger).whenComplete { result in
7171
switch result {

Diff for: Sources/AsyncHTTPClient/ConnectionPool/HTTPConnectionPool.swift

+38-9
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,7 @@ final class HTTPConnectionPool {
130130
}
131131

132132
private let stateLock = Lock()
133-
private var _state: StateMachine {
134-
didSet {
135-
self.logger.trace("Connection Pool State changed", metadata: [
136-
"key": "\(self.key)",
137-
"state": "\(self._state)",
138-
])
139-
}
140-
}
133+
private var _state: StateMachine
141134

142135
private static let fallbackConnectTimeout: TimeAmount = .seconds(30)
143136

@@ -175,6 +168,8 @@ final class HTTPConnectionPool {
175168
self.clientConfiguration = clientConfiguration
176169
self.key = key
177170
self.delegate = delegate
171+
var logger = logger
172+
logger[metadataKey: "ahc-pool-key"] = "\(key)"
178173
self.logger = logger
179174

180175
self.idleConnectionTimeout = clientConfiguration.connectionPool.idleTimeout
@@ -222,7 +217,11 @@ final class HTTPConnectionPool {
222217
self.cancelIdleTimerForConnection(connectionID)
223218

224219
case .closeConnection(let connection, isShutdown: let isShutdown):
225-
// we are not interested in the close future...
220+
self.logger.trace("close connection", metadata: [
221+
"ahc-connection-id": "\(connection.id)",
222+
])
223+
224+
// we are not interested in the close promise...
226225
connection.close(promise: nil)
227226

228227
if case .yes(let unclean) = isShutdown {
@@ -289,6 +288,9 @@ final class HTTPConnectionPool {
289288
}
290289

291290
private func createConnection(_ connectionID: Connection.ID, on eventLoop: EventLoop) {
291+
self.logger.trace("Opening fresh connection", metadata: [
292+
"ahc-connection-id": "\(connectionID)",
293+
])
292294
// Even though this function is called make it actually creates/establishes a connection.
293295
// TBD: Should we rename it? To what?
294296
self.connectionFactory.makeConnection(
@@ -353,6 +355,9 @@ final class HTTPConnectionPool {
353355
}
354356

355357
private func scheduleIdleTimerForConnection(_ connectionID: Connection.ID, on eventLoop: EventLoop) {
358+
self.logger.trace("Schedule idle connection timeout timer", metadata: [
359+
"ahc-connection-id": "\(connectionID)",
360+
])
356361
let scheduled = eventLoop.scheduleTask(in: self.idleConnectionTimeout) {
357362
// there might be a race between a cancelTimer call and the triggering
358363
// of this scheduled task. both want to acquire the lock
@@ -375,6 +380,10 @@ final class HTTPConnectionPool {
375380
}
376381

377382
private func cancelIdleTimerForConnection(_ connectionID: Connection.ID) {
383+
self.logger.trace("Cancel idle connection timeout timer", metadata: [
384+
"ahc-connection-id": "\(connectionID)",
385+
])
386+
378387
let cancelTimer = self.timerLock.withLock {
379388
self._idleTimer.removeValue(forKey: connectionID)
380389
}
@@ -387,6 +396,10 @@ final class HTTPConnectionPool {
387396
_ timeAmount: TimeAmount,
388397
on eventLoop: EventLoop
389398
) {
399+
self.logger.trace("Schedule connection creation backoff timer", metadata: [
400+
"ahc-connection-id": "\(connectionID)",
401+
])
402+
390403
let scheduled = eventLoop.scheduleTask(in: timeAmount) {
391404
// there might be a race between a backoffTimer and the pool shutting down.
392405
let timerExisted = self.timerLock.withLock {
@@ -420,6 +433,10 @@ final class HTTPConnectionPool {
420433

421434
extension HTTPConnectionPool: HTTPConnectionRequester {
422435
func http1ConnectionCreated(_ connection: HTTP1Connection) {
436+
self.logger.trace("successfully created connection", metadata: [
437+
"ahc-connection-id": "\(connection.id)",
438+
"ahc-http-version": "http/1.1",
439+
])
423440
let action = self.stateLock.withLock {
424441
self._state.newHTTP1ConnectionCreated(.http1_1(connection))
425442
}
@@ -442,6 +459,10 @@ extension HTTPConnectionPool: HTTPConnectionRequester {
442459
}
443460

444461
func failedToCreateHTTPConnection(_ connectionID: HTTPConnectionPool.Connection.ID, error: Error) {
462+
self.logger.debug("connection attempt failed", metadata: [
463+
"ahc-error": "\(error)",
464+
"ahc-connection-id": "\(connectionID)",
465+
])
445466
let action = self.stateLock.withLock {
446467
self._state.failedToCreateNewConnection(error, connectionID: connectionID)
447468
}
@@ -451,13 +472,21 @@ extension HTTPConnectionPool: HTTPConnectionRequester {
451472

452473
extension HTTPConnectionPool: HTTP1ConnectionDelegate {
453474
func http1ConnectionClosed(_ connection: HTTP1Connection) {
475+
self.logger.debug("connection closed", metadata: [
476+
"ahc-connection-id": "\(connection.id)",
477+
"ahc-http-version": "http/1.1",
478+
])
454479
let action = self.stateLock.withLock {
455480
self._state.connectionClosed(connection.id)
456481
}
457482
self.run(action: action)
458483
}
459484

460485
func http1ConnectionReleased(_ connection: HTTP1Connection) {
486+
self.logger.trace("releasing connection", metadata: [
487+
"ahc-connection-id": "\(connection.id)",
488+
"ahc-http-version": "http/1.1",
489+
])
461490
let action = self.stateLock.withLock {
462491
self._state.http1ConnectionReleased(connection.id)
463492
}

Diff for: Sources/AsyncHTTPClient/RequestBag.swift

+2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ final class RequestBag<Delegate: HTTPClientResponseDelegate> {
7373
}
7474

7575
private func requestWasQueued0(_ scheduler: HTTPRequestScheduler) {
76+
self.logger.debug("Request was queued (waiting for a connection to become available)")
77+
7678
self.task.eventLoop.assertInEventLoop()
7779
self.state.requestWasQueued(scheduler)
7880
}

0 commit comments

Comments
 (0)