A simple logging middleware to help keep user information out of logs.
Keeping your logs clear of personal user information and other private data is hard. PrivacyAwareLogTransformer helps you make intentional decisions about what to log.
Currently, developers need to be cautious with each log message they write to ensure that they are not leaking personal data. This is both tedious and error-prone, so why not ask the compiler to do protect from logging private data unintentionally.
PrivacyAwareLogTransformer ensures any variables emitted in logs have been sanitized. It then removes those variables and inserts a token while attaching the variable values in a dictionary.
As an added benefit, every log message will be emitted the same way regardless of the variables. This allows trend monitoring and alerting to work well since the log messages will not appear as different strings and therefore confuse the alerting system.
Basically:
logger.log("a message with an object: \(User(name: "Bob"))")
Becomes:
message: a message with an object: {{user_1}}, properties: ["user_1": "<safe value>"]
Swift Package Manager is the recommended way of consuming PrivacyAwareLogTransformer.
To integrate it, add a dependency in your Package.swift
:
dependencies: [
.package(url: "https://github.com/rimarsh/PrivacyAwareLogTransformer.git", from: "1.0")
],
To integrate PrivacyAwareLogTransformer into your Xcode project using CocoaPods, specify it in your Podfile
:
pod 'PrivacyAwareLogTransformer', :git => 'https://github.com/rimarsh/PrivacyAwareLogTransformer.git'
To integrate PrivacyAwareLogTransformer into your Xcode project using Carthage, specify it in your Cartfile
:
github "rimarsh/PrivacyAwareLogTransformer"
PrivacyAwareLogReceiver
to take transformed logs and send them to an existing logging infrastructure:import PrivacyAwareLogTransformer
class LogReceiver: PrivacyAwareLogReceiver {
func log(_ message: String, properties: [String : String]?, context: [AnyHashable : Any]?) {
print("message: \(message), properties: \(properties ?? [:]), context: \(context ?? [:])")
}
}
import PrivacyAwareLogTransformer
let receiver = LogReceiver()
var logger = PrivacyAwareLogTransformer()
logger.receiver = receiver
Assume, for example, two example data structures (one implements PrivacyAwareLoggable
and the other does not):
struct User: PrivacyAwareLoggable {
let userId: UUID = UUID()
let name: String
var loggingValue: String {
return userId.uuidString
}
}
struct Team {
let team: UUID = UUID()
let name: String
}
Logging a static string is just like any other log mechanism.
logger.log("a basic message")
Output:
message: a basic message, properties: nil, context: nil
When logging an object, the object must conform to PrivacyAwareLoggable
.
logger.log("a message with an object: \(User(name: "Bob"))")
Output:
message: a message with an object: {{user_1}}, properties: ['user_1': <uuid>], context: nil
If the object doesn't conform to PrivacyAwareLoggable
, it will fail to compile.
logger.log("a message with an object: \(Team(name: "My Team"))")
Feel free to dive in! Open an issue or submit a PR.
MIT © Riley Marsh. See the LICENSE file for more information.
link |
Stars: 0 |
Last commit: 4 years ago |
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics