Event logging for client applications on Apple platforms with support for offline work and automatic upload to Google Cloud (GCP). The package depends on SwiftLog - an official logging API for Swift, so it can be easly integrated into the project and combined with other logging backends. Log events are stored locally in the JSON Lines file format and bulk uploaded to GCP using the Cloud Logging API v2 at time intervals, upon defined event or explicit request.
And yes, it logs itself! (with recursion protection) 🤘
Google-recommended logging solution for client applications is the Analytics framework, which is now part of the Firebase SDK. Here is a comparison of their framework and this library in terms of logging:
Library | FirebaseAnalytics | GoogleCloudLogging |
---|---|---|
Platform | Mobile only. Even Catalyst is not currently supported. | All modern Apple's OSs. It is essential for development of universal SwiftUI apps. |
Source code | Closed source. All application and users data is available to Google. | Open source. A few hundred lines of pure Swift, no implicit data submission. |
Dependences | Part of the Firebase SDK. Brings a bunch of Objective-C/C++ code with runtime swizzling etc. | Only relies on SwiftLog and Apple's embedded frameworks. |
Distribution | CocoaPods/Carthage. SwiftPM is currently cannot be supported due to closed source and dependencies. | SwiftPM, which is preferred as integrated with the Swift build system. |
Backend | Google Analytics for Firebase. Includes some predefined marketing tools. | GCP Operations (formerly Stackdriver). Flexible custom log views, metrics, notifications, export etc. |
Integration | Registration of your app in Google is required. | Only need to generate an access key. |
Logging | Proprietary logging functions and implicit usage tracking. | SwiftLog logging API. Single line connection of logging backend. |
Open your application project in Xcode 11 or later, go to menu File -> Swift Packages -> Add Package Dependency...
and paste the package repository URL https://github.com/DnV1eX/GoogleCloudLogging.git
.
In your web browser, open the Google Cloud Console and create a new project. In IAM & Admin -> Service Accounts
create a service account choosing Logging -> Logs Writer
role. In the last step, create and download private key choosing JSON
format. You need to include this file in your application bundle.
Just drag the file into the Xcode project and tick the desired targets in the file inspector.
Import both SwiftLog
and GoogleCloudLogging
modules:
import Logging
import GoogleCloudLogging
Register the logging backend once after the app launch:
LoggingSystem.bootstrap(GoogleCloudLogHandler.init)
Alternatively, you can register several backends, for example, in order to send logs to both GCP and the Xcode console:
LoggingSystem.bootstrap { MultiplexLogHandler([GoogleCloudLogHandler(label: $0), StreamLogHandler.standardOutput(label: $0)]) }
Configure GoogleCloudLogHandler:
do {
try GoogleCloudLogHandler.setup(serviceAccountCredentials: Bundle.main.url(forResource: /* GCP private key file name */, withExtension: "json")!, clientId: UIDevice.current.identifierForVendor)
} catch {
// Log GoogleCloudLogHandler setup error
}
If UIKit is not available, you can generate random clientId
using UUID()
and store it between the app launches.
You can customize GoogleCloudLogHandler's static variables which are all thread safe and documented in the source code.
It is recommended to explicitly upload logs calling
GoogleCloudLogHandler.upload()
when hiding or exiting the app.
Import SwiftLog
module into the desired file:
import Logging
Create logger
which can be a type, instance, or global constant or variable:
static let logger = Logger(label: /* Logged class name */)
You can customize the minimum emitted log level and set the logger metadata.
Emit log messages in a certain log level:
logger.info(/* Logged info message */)
logger.error(/* Logged error message */, metadata: [LogKey.error: "\(error)"])
It is a good practice to define
typealias LogKey = GoogleCloudLogHandler.MetadataKey
and extend it with your custom keys rather than use string literals.
GoogleCloudLogHandler.globalMetadata
takes precedence overLogger
metadata which in turn takes precedence over log message metadata in case of key overlapping.
In your web browser, open the GCP Operations Logging and select your project. You will see a list of logs for a given time range which can be filtered by log name (logger label), severity (log level), text payload (message), labels (metadata) etc. Resource type for logs produced by GoogleCloudLogHandler is always Global.
You can switch to the new Logs Viewer Preview that introduces new features, such as advanced log queries and histograms.
Click on clientId label value of the desired log entry and pick "Show matching entries" in order to view logs from the same app instance only.
Copyright © 2020 DnV1eX. All rights reserved. Licensed under the Apache License, Version 2.0.