Skip to content

logging support #227

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2020
Merged
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
1 change: 1 addition & 0 deletions .swiftformat
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
--patternlet inline
--stripunusedargs unnamed-only
--ranges nospace
--disable typeSugar # https://github.com/nicklockwood/SwiftFormat/issues/636
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Annoying that it did so, but great that quick turnaround on the ticket :)


# rules
7 changes: 5 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,18 @@ let package = Package(
.package(url: "https://github.com/apple/swift-nio-ssl.git", from: "2.7.0"),
.package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.3.0"),
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.5.1"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"),
],
targets: [
.target(
name: "AsyncHTTPClient",
dependencies: ["NIO", "NIOHTTP1", "NIOSSL", "NIOConcurrencyHelpers", "NIOHTTPCompression", "NIOFoundationCompat", "NIOTransportServices"]
dependencies: ["NIO", "NIOHTTP1", "NIOSSL", "NIOConcurrencyHelpers", "NIOHTTPCompression",
"NIOFoundationCompat", "NIOTransportServices", "Logging"]
),
.testTarget(
name: "AsyncHTTPClientTests",
dependencies: ["NIO", "NIOConcurrencyHelpers", "NIOSSL", "AsyncHTTPClient", "NIOFoundationCompat", "NIOTestUtils"]
dependencies: ["NIO", "NIOConcurrencyHelpers", "NIOSSL", "AsyncHTTPClient", "NIOFoundationCompat",
"NIOTestUtils", "Logging"]
),
]
)
132 changes: 97 additions & 35 deletions Sources/AsyncHTTPClient/ConnectionPool.swift

Large diffs are not rendered by default.

232 changes: 207 additions & 25 deletions Sources/AsyncHTTPClient/HTTPClient.swift

Large diffs are not rendered by default.

35 changes: 25 additions & 10 deletions Sources/AsyncHTTPClient/HTTPHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//

import Foundation
import Logging
import NIO
import NIOConcurrencyHelpers
import NIOFoundationCompat
Expand Down Expand Up @@ -533,17 +534,19 @@ extension HTTPClient {
var connection: Connection?
var cancelled: Bool
let lock: Lock
let logger: Logger // We are okay to store the logger here because a Task is for only ond request.

init(eventLoop: EventLoop) {
init(eventLoop: EventLoop, logger: Logger) {
self.eventLoop = eventLoop
self.promise = eventLoop.makePromise()
self.completion = self.promise.futureResult.map { _ in }
self.cancelled = false
self.lock = Lock()
self.logger = logger
}

static func failedTask(eventLoop: EventLoop, error: Error) -> Task<Response> {
let task = self.init(eventLoop: eventLoop)
static func failedTask(eventLoop: EventLoop, error: Error, logger: Logger) -> Task<Response> {
let task = self.init(eventLoop: eventLoop, logger: logger)
task.promise.fail(error)
return task
}
Expand Down Expand Up @@ -585,13 +588,18 @@ extension HTTPClient {
}
}

func succeed<Delegate: HTTPClientResponseDelegate>(promise: EventLoopPromise<Response>?, with value: Response, delegateType: Delegate.Type, closing: Bool) {
self.releaseAssociatedConnection(delegateType: delegateType, closing: closing).whenSuccess {
func succeed<Delegate: HTTPClientResponseDelegate>(promise: EventLoopPromise<Response>?,
with value: Response,
delegateType: Delegate.Type,
closing: Bool) {
self.releaseAssociatedConnection(delegateType: delegateType,
closing: closing).whenSuccess {
promise?.succeed(value)
}
}

func fail<Delegate: HTTPClientResponseDelegate>(with error: Error, delegateType: Delegate.Type) {
func fail<Delegate: HTTPClientResponseDelegate>(with error: Error,
delegateType: Delegate.Type) {
if let connection = self.connection {
self.releaseAssociatedConnection(delegateType: delegateType, closing: true)
.whenSuccess {
Expand All @@ -601,13 +609,14 @@ extension HTTPClient {
}
}

func releaseAssociatedConnection<Delegate: HTTPClientResponseDelegate>(delegateType: Delegate.Type, closing: Bool) -> EventLoopFuture<Void> {
func releaseAssociatedConnection<Delegate: HTTPClientResponseDelegate>(delegateType: Delegate.Type,
closing: Bool) -> EventLoopFuture<Void> {
if let connection = self.connection {
// remove read timeout handler
return connection.removeHandler(IdleStateHandler.self).flatMap {
connection.removeHandler(TaskHandler<Delegate>.self)
}.map {
connection.release(closing: closing)
connection.release(closing: closing, logger: self.logger)
}.flatMapError { error in
fatalError("Couldn't remove taskHandler: \(error)")
}
Expand Down Expand Up @@ -639,6 +648,7 @@ internal class TaskHandler<Delegate: HTTPClientResponseDelegate>: RemovableChann
let delegate: Delegate
let redirectHandler: RedirectHandler<Delegate.Response>?
let ignoreUncleanSSLShutdown: Bool
let logger: Logger // We are okay to store the logger here because a TaskHandler is just for one request.

var state: State = .idle
var pendingRead = false
Expand All @@ -656,12 +666,14 @@ internal class TaskHandler<Delegate: HTTPClientResponseDelegate>: RemovableChann
kind: HTTPClient.Request.Kind,
delegate: Delegate,
redirectHandler: RedirectHandler<Delegate.Response>?,
ignoreUncleanSSLShutdown: Bool) {
ignoreUncleanSSLShutdown: Bool,
logger: Logger) {
self.task = task
self.delegate = delegate
self.redirectHandler = redirectHandler
self.ignoreUncleanSSLShutdown = ignoreUncleanSSLShutdown
self.kind = kind
self.logger = logger
}
}

Expand Down Expand Up @@ -717,7 +729,10 @@ extension TaskHandler {
do {
let result = try body(self.task)

self.task.succeed(promise: promise, with: result, delegateType: Delegate.self, closing: self.closing)
self.task.succeed(promise: promise,
with: result,
delegateType: Delegate.self,
closing: self.closing)
} catch {
self.task.fail(with: error, delegateType: Delegate.self)
}
Expand Down
40 changes: 40 additions & 0 deletions Sources/AsyncHTTPClient/NoOpLogHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the AsyncHTTPClient open source project
//
// Copyright (c) 2020 Apple Inc. and the AsyncHTTPClient project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

import Logging

internal struct NoOpLogHandler: LogHandler {
func log(level: Logger.Level, message: Logger.Message, metadata: Logger.Metadata?, file: String, function: String, line: UInt) {}

subscript(metadataKey _: String) -> Logger.Metadata.Value? {
get {
return nil
}
set {}
}

var metadata: Logger.Metadata {
get {
return [:]
}
set {}
}

var logLevel: Logger.Level {
get {
return .critical
}
set {}
}
}
31 changes: 31 additions & 0 deletions Sources/AsyncHTTPClient/StringConvertibleInstances.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the AsyncHTTPClient open source project
//
// Copyright (c) 2020 Apple Inc. and the AsyncHTTPClient project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of AsyncHTTPClient project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

extension Connection: CustomStringConvertible {
var description: String {
return "\(self.channel)"
}
}

extension HTTP1ConnectionProvider.Waiter: CustomStringConvertible {
var description: String {
return "HTTP1ConnectionProvider.Waiter(\(self.preference))"
}
}

extension HTTPClient.EventLoopPreference: CustomStringConvertible {
public var description: String {
return "\(self.preference)"
}
}
Loading