SmartLogMacro

1.1.0

AndriyGo/SmartLogMacro

What's New

1.1.0

2025-04-11T11:47:57Z

Full Changelog: 1.0.2...1.1.0

SmartLogMacro

✨ Swift macros for easier logging via Apple’s unified logging system with optional 3rd-party logging support (e.g. Crashlytics)

SPM Compatible License Buy Me a Coffee

#smartLog(logger, .info, "User \(userId) signed out at \(Date())")

Expands to:

{
    logger.log(level: .info, "User \(userId) signed out at \(Date())")
    SmartLogMacroCustomLogger.log("User \(userId) signed out at \(Date())")
}()

✅ Key benefits

  • 🔐 Privacy made easy – apply a single privacy setting to all interpolated values
  • 🔁 Optional external logging – forward the log message to any function (e.g. Crashlytics.crashlytics().log)
  • Zero runtime overhead – macro expands at compile-time

📦 Installation

SmartLogMacro is available via Swift Package Manager.

To add it to your project in Xcode:

  1. Open your project.
  2. Go to File → Add Packages...
  3. Enter the URL: https://github.com/andriyGo/SmartLogMacro
  4. Select the version you want to use and press Add Package.

Or, add it manually to your Package.swift:

dependencies: [
    .package(url: "https://github.com/andriyGo/SmartLogMacro", from: "1.0.0")
]

Then add SmartLogMacro to your target dependencies:

.target(
    name: "MyTarget",
    dependencies: [.product(name: "SmartLogMacro", package: "SmartLogMacro")]
)

🧾 Available macros

Macro Privacy Level External Logging Description
#log configurable optional Full control over logging behaviour
#logPublic .public optional Shortcut for always-public logs
#smartLog configurable always enabled Forwards to SmartLogMacroCustomLogger.log
#smartLogPublic .public always enabled Simplest usage – public logs + external forwarding

🚀 Usage

🔐 One-line privacy control for multiple values

With Apple's Logger:

logger.info("Item \(item, privacy: .public) at \(indexPath, privacy: .public)")

With SmartLogMacro:

#log(logger, .info, "Item \(item) at \(indexPath)", privacy: .public)

Expands to:

logger.log(level: .info, "Item \(item, privacy: .public) at \(indexPath, privacy: .public)")

Or even shorter:

#logPublic(logger, .info, "Item \(item) at \(indexPath)")

🔁 Send logs to 3rd-party systems (like Crashlytics)

Using #smartLog or #smartLogPublic

#smartLog(logger, .error, "Sign-out failed for user: \(userId)")
#smartLogPublic(logger, .info, "User signed in: \(userId)")

To enable this, define:

struct SmartLogMacroCustomLogger {
    static func log(_ message: String) {
        Crashlytics.crashlytics().log(message)
    }
}

Or use:

typealias SmartLogMacroCustomLogger = MyLogger

Fine-grained control

#log(logger, .error, "Error: \(error)", customLoggingFunction: Crashlytics.crashlytics().log)
#logPublic(logger, .error, "Unexpected logout", customLoggingFunction: MyLogger.send)

Define your own custom logger:

struct CustomLogger {
    static func log(_ message: String) {
        Crashlytics.crashlytics().log(message)
        Analytics.logEvent("log", parameters: ["message": message])
    }
}

⚠️ Limitations

  1. No trailing closure support for customLoggingFunction
  2. Expanded macro uses a code block
    May affect Xcode console line numbers.
  3. No prefixing or metadata in external logs
    Only raw message is passed.

💬 Most of these limitations stem from the desire to keep SmartLogMacro lightweight and simple in v1.


🤝 Contributions

Contributions are welcome!
Open an issue or pull request — all feedback is appreciated.


☕️ Support

Enjoying SmartLogMacro?
Buy me a coffee ☕💙


📄 License

SmartLogMacro is available under the Apache License 2.0.
See the LICENSE file for full details.

Description

  • Swift Tools 6.1.0
View More Packages from this Author

Dependencies

Last updated: Thu May 08 2025 10:13:27 GMT-0900 (Hawaii-Aleutian Daylight Time)