Giter Club home page Giter Club logo

aws-xray-sdk-swift's Introduction

aws-xray-sdk-swift

CI codecov

Unofficial AWS X-Ray Recorder SDK for Swift.

Getting started

Installation

Add a dependency using Swift Package Manager.

dependencies: [
    .package(url: "https://github.com/pokryfka/aws-xray-sdk-swift.git", from: "0.3.0")
]

Recording

Create an instance of XRayRecorder:

let recorder = XRayRecorder()

Begin and end (sub)segments explicitly:

let segment = recorder.beginSegment(name: "Segment 1")
usleep(100_000)
segment.end()

use closures for convenience:

recorder.segment(name: "Segment 2") { segment in
    try? segment.subsegment(name: "Subsegment 2.1") { segment in
        _ = segment.subsegment(name: "Subsegment 2.1.1 with Result") { _ -> String in
            usleep(100_000)
            return "Result"
        }
        try segment.subsegment(name: "Subsegment 2.1.2 with Error") { _ in
            usleep(200_000)
            throw ExampleError.test
        }
    }
}

Emitting

Events are emitted as soon as they end.

Subsegments have to be created before the parent segment ended.

Subsegments may end after their parent segment ended, in which case they will be presented as Pending until they end.

Make sure all segments are sent before program exits:

recorder.wait()

Result in AWS X-Ray console:

Screenshot of the AWS X-Ray console

See AWSXRayRecorderExample/main.swift for a complete example.

Segments and subsegments can include an annotations object containing one or more fields that X-Ray indexes for use with filter expressions. (...)

segment.setAnnotation("zip_code", value: 98101)

Segments and subsegments can include a metadata object containing one or more fields with values of any type, including objects and arrays. X-Ray does not index metadata (...)

segment.setMetadata(["debug": ["test": "Metadata string"]])

AWS SDK (WIP)

Record AWSClient requests with XRayMiddleware:

let awsClient = AWSClient(
    middlewares: [XRayMiddleware(recorder: recorder, name: "S3")],
    httpClientProvider: .shared(httpClient)
)
let s3 = S3(client: awsClient)

and/or recording SwiftNIO futures:

recorder.segment(name: "List Buckets") {
    s3.listBuckets()
}

Result in AWS X-Ray console:

Screenshot of the AWS X-Ray console

See AWSXRayRecorderExampleSDK/main.swift for a complete example.

AWS Lambda using Swift AWS Lambda Runtime

Enable tracing as described in Using AWS Lambda with AWS X-Ray.

Note that:

Lambda runs the daemon automatically any time a function is invoked for a sampled request.

Make sure to flush the recorder in each invocation:

private struct ExampleLambdaHandler: EventLoopLambdaHandler {
    typealias In = Cloudwatch.ScheduledEvent
    typealias Out = Void

    private let recorder = XRayRecorder()

    private func doWork(on eventLoop: EventLoop) -> EventLoopFuture<Void> {
        eventLoop.submit { usleep(100_000) }.map { _ in }
    }

    func handle(context: Lambda.Context, event: In) -> EventLoopFuture<Void> {
        recorder.segment(name: "ExampleLambdaHandler", context: context) {
            self.doWork(on: context.eventLoop)
        }.flatMap {
            self.recorder.flush(on: context.eventLoop)
        }
    }
}

See AWSXRayRecorderExampleLambda/main.swift for a complete example.

Configuration

The library’s behavior can be configured using environment variables:

  • AWS_XRAY_SDK_DISABLED: set true to disable tracing, enabled by default.
  • AWS_XRAY_DAEMON_ADDRESS – the IP address and port of the X-Ray daemon, 127.0.0.1:2000 by default.
  • XRAY_RECORDER_LOG_LEVEL: swift-log logging level, info by default.

Alternatively XRayRecorder can be configured using XRayRecorder.Config which will override environment variables:

let recorder = XRayRecorder(
    config: .init(enabled: true,
                  logLevel: .debug,
                  daemonEndpoint: "127.0.0.1:2000",
                  serviceVersion: "aws-xray-sdk-swift-example-sdk")
)                  

SwiftNIO

Segments can be emitted on provided SwiftNIO EventLoopGroup:

let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let eventLoop = group.next()
let recorder = XRayRecorder(eventLoopGroup: group)

// ...

try recorder.flush(on: eventLoop).wait()

Custom emitter

By default events are sent as UDP to AWS X-Ray daemon which buffers and relays it to AWS X-Ray API.

A custom emitter has to implement XRayEmitter protocol:

public protocol XRayEmitter {
    func send(_ segment: XRayRecorder.Segment)
    func flush(_ callback: @escaping (Error?) -> Void)
}

example of an emitter which logs emitted segments:

public struct XRayLogEmitter: XRayEmitter {
    private let logger: Logger

    private let encoder: JSONEncoder = {
        let encoder = JSONEncoder()
        encoder.outputFormatting = .prettyPrinted
        return encoder
    }()

    public init(label: String? = nil) {
        let label = label ?? "xray.log_emitter.\(String.random32())"
        logger = Logger(label: label)
    }

    public func send(_ segment: XRayRecorder.Segment) {
        do {
            let document: String = try encoder.encode(segment)
            logger.info("\n\(document)")
        } catch {
            logger.error("Failed to encode a segment: \(error)")
        }
    }

    public func flush(_: @escaping (Error?) -> Void) {}
}

The emitter has to be provided when creating an instance of XRayRecorder:

let recorder = XRayRecorder(emitter: XRayNoOpEmitter())

References

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.