Contents

AndriyGo/SmartLogMacro

[![SPM Compatible](https://img.shields.io/badge/SPM-compatible-brightgreen?logo=swift)](https://swift.org/package-manager/) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Buy Me a Coffee](https://img.shields.io/badge/Buy%20me%20a%20coffee-%E2%98%95-blue?logo=buymeacoffee&logoColor=white&style=flat)](https://www.buymeacoffee.com/andriyGo)

βœ… 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)
  • 🏷️ Automatic formatting β€” external logs include logger category and severity level
  • ⚑ 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")]
)

πŸš€ 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)

External logs are automatically formatted with [category] Level: message for better readability and filtering.

Using #smartLog or #smartLogPublic
#smartLog(.auth, .error, "Sign-out failed for user: \(userId)")
#smartLogPublic(.network, .info, "Request completed in \(duration)ms")

External logs will appear as:

[auth] Error: Sign-out failed for user: 12345
[network] Info: Request completed in 234ms

To enable this, define:

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

Or use:

typealias SmartLogMacroCustomLogger = MyLogger

Fine-grained control
#log(.database, .error, "Query failed: \(error)", customLoggingFunction: Crashlytics.crashlytics().log)
#logPublic(.api, .debug, "Response received", customLoggingFunction: MyLogger.send)

External logs will be formatted as:

[database] Error: Query failed: timeout
[api] Debug: Response received

Define your own custom logger:

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

🏷️ Logger Category Extraction

SmartLogMacro automatically extracts the logger category for external logging:

// Using shorthand syntax (.network)
#smartLogPublic(.network, .info, "Request sent")
// External log: "[network] Info: Request sent"

// Using full syntax (Logger.auth)
#smartLogPublic(Logger.auth, .error, "Login failed")
// External log: "[auth] Error: Login failed"

// Using variable names
let apiLogger = Logger(...)
#smartLogPublic(apiLogger, .debug, "Testing")
// External log: "[apiLogger] Debug: Testing"

The category and log level are extracted at compile-time with zero runtime overhead.


⚠️ Limitations

  1. No trailing closure support for customLoggingFunction
  2. Expanded macro expands to a single-line tuple expression

This avoids introducing extra lines, but the expression result is discarded with _ = (...).

  1. Category extraction requires consistent naming

Use .categoryName or Logger.categoryName syntax for best results.

πŸ’¬ Most of these limitations stem from the desire to keep SmartLogMacro lightweight and simple until community feedback arrives.


🀝 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.

Package Metadata

Repository: AndriyGo/SmartLogMacro

Stars: 13

Forks: 3

Open issues: 0

Default branch: main

Primary language: swift

License: Apache-2.0

README: README.md