TelemetryDeck / Issues

When something is wrong in TelemetryDeck-Land, or if you have a cool idea how to make things better, this is the place to create an Issue.
https://telemetrydeck.com
37 stars 0 forks source link

Support for Vapor Backend #480

Open mpdifran opened 1 week ago

mpdifran commented 1 week ago

Hi, I'd love to see official support for Vapor for the TD SDK. I've created some wrappers to integrate with Application and Request, but looks like there's a compile issue when I try to deploy to Linux:

[97/926] Compiling TelemetryDeck CryptoHashing.swift
/tmp/build_5ea4ecc3/Backend/Bloom-Backend/.build/checkouts/SwiftSDK/Sources/TelemetryDeck/Helpers/CryptoHashing.swift:4:8: error: no such module 'CommonCrypto'
 2 | import CryptoKit
 3 | #endif
 4 | import CommonCrypto
   |        `- error: no such module 'CommonCrypto'
 5 | import Foundation
 6 |

Here's the wrappers I've created in case you want to pick this up:

// Application+TelemetryDeck.swift

import TelemetryDeck
import Vapor

extension Application {
    var telemetryDeck: TelemetryWrapper {
        TelemetryWrapper(app: self)
    }

    struct TelemetryWrapper {
        private let app: Application

        init(app: Application) {
            self.app = app
        }
    }
}

extension Application.TelemetryWrapper {

    func initialize(appID: String) {
        var config = TelemetryDeck.Config(appID: appID)
        config.testMode = !app.environment.isRelease
        TelemetryDeck.initialize(config: config)
    }

    func signal(
        _ signalName: String,
        parameters: [String: String] = [:],
        floatValue: Double? = nil,
        customUserID: String? = nil
    ) {
        TelemetryDeck.signal(
            signalName,
            parameters: parameters,
            floatValue: floatValue,
            customUserID: customUserID
        )
    }

    func errorOccurred(
        id: String,
        category: ErrorCategory? = nil,
        message: String? = nil,
        parameters: [String: String] = [:],
        floatValue: Double? = nil,
        customUserID: String? = nil
    ) {
        TelemetryDeck.errorOccurred(
            id: id,
            category: category,
            message: message,
            parameters: parameters,
            floatValue: floatValue,
            customUserID: customUserID
        )
    }

    func errorOccurred(
        identifiableError: IdentifiableError,
        category: ErrorCategory = .thrownException,
        message: String? = nil,
        parameters: [String: String] = [:],
        floatValue: Double? = nil,
        customUserID: String? = nil
    ) {
        TelemetryDeck.errorOccurred(
            identifiableError: identifiableError,
            category: category,
            message: message,
            parameters: parameters,
            floatValue: floatValue,
            customUserID: customUserID
        )
    }
}
// Request+TelemetryDeck.swift

import TelemetryDeck
import Vapor

extension Request {
    var telemetryDeck: TelemetryWrapper {
        TelemetryWrapper(app: application, request: self)
    }

    struct TelemetryWrapper {
        private let app: Application
        private let request: Request

        init(app: Application, request: Request) {
            self.app = app
            self.request = request
        }
    }
}

extension Request.TelemetryWrapper {

    func signal(
        _ signalName: String,
        parameters: [String: String] = [:],
        floatValue: Double? = nil
    ) {
        TelemetryDeck.signal(
            signalName,
            parameters: parameters,
            floatValue: floatValue,
            customUserID: userIdentifier
        )
    }

    func errorOccurred(
        id: String,
        category: ErrorCategory? = nil,
        message: String? = nil,
        parameters: [String: String] = [:],
        floatValue: Double? = nil
    ) {
        TelemetryDeck.errorOccurred(
            id: id,
            category: category,
            message: message,
            parameters: parameters,
            floatValue: floatValue,
            customUserID: userIdentifier
        )
    }

    func errorOccurred(
        identifiableError: IdentifiableError,
        category: ErrorCategory = .thrownException,
        message: String? = nil,
        parameters: [String: String] = [:],
        floatValue: Double? = nil
    ) {
        TelemetryDeck.errorOccurred(
            identifiableError: identifiableError,
            category: category,
            message: message,
            parameters: parameters,
            floatValue: floatValue,
            customUserID: userIdentifier
        )
    }
}

private extension Request.TelemetryWrapper {

    var userIdentifier: String? {
        request.headers.first(name: .xForwardedFor)?.components(separatedBy: ",").first ?? request.remoteAddress?.description
    }
}
mpdifran commented 1 week ago

Apparently the recommended library for server side crypto is Apple's swift-crypto, but that has a minimum macOS version of 15 (compared to TD's 13). AFAIK there's no way to conditionally link to the library based on macOS version.