Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change DDLogLevel from enum to options #1249

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

nhgrif
Copy link

@nhgrif nhgrif commented Aug 27, 2021

New Pull Request Checklist

  • I have read and understood the CONTRIBUTING guide

  • I have read the Documentation

  • I have searched for a similar pull request in the project and found none

  • I have updated this branch with the latest master to avoid conflicts (via merge from master or rebase)

  • I have added the required tests to prove the fix/feature I am adding

  • I have updated the documentation (if necessary)

  • I have run the tests and they pass

  • I have run the lint and it passes (pod lib lint)

This merge request fixes / refers to the following issues: n/a

Pull Request Description

As discussed in this StackOverflow question, there's not really a clean way to implement custom log levels in Swift.

As DDLogFlag is defined as NS_OPTIONS, absolutely any value is valid here, but with DDLogLevel defined as an enum, as far as Swift as concerned the existing levels are the only valid levels. I can't even particularly cleanly write aliases for the existing levels.

Further, to me, it doesn't even make particular sense for DDLogFlag to be NS_OPTIONS while DDLogLevel is NS_ENUM. If anything, shouldn't it almost be the opposite...? Logically, it doesn't make sense that something might be logged as [.error, .info] from Swift, but you could log something using that flag... but what does that even mean? Meanwhile, from Swift, I can not do as some CocoaLumberjack documentation suggests, and easily filter to say "show me .info level, but not .warnings, but do show me .error level". This again comes back to the fact that DDLogLevel is an enum and from the Swift side I can not create any custom values for this.

By this logic, DDLogFlag itself should arguably be NS_ENUM rather than NS_OPTION, however, I recommend leaving it as NS_OPTION, because changing it to NS_ENUM once again would limit my ability to use custom log levels from Swift.

@codecov
Copy link

codecov bot commented Aug 27, 2021

Codecov Report

Merging #1249 (c74d51b) into master (80ada1f) will decrease coverage by 2.17%.
The diff coverage is n/a.

❗ Current head c74d51b differs from pull request most recent head c3afb09. Consider uploading reports for the commit c3afb09 to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1249      +/-   ##
==========================================
- Coverage   47.58%   45.41%   -2.18%     
==========================================
  Files          32       26       -6     
  Lines        5174     4391     -783     
  Branches      484        0     -484     
==========================================
- Hits         2462     1994     -468     
+ Misses       2540     2397     -143     
+ Partials      172        0     -172     
Impacted Files Coverage Δ
Sources/CocoaLumberjack/DDAbstractDatabaseLogger.m 9.37% <0.00%> (-1.49%) ⬇️
...umberjack/Extensions/DDDispatchQueueLogFormatter.m 9.83% <0.00%> (-1.44%) ⬇️
Tests/CocoaLumberjackTests/DDLogTests.m 97.43% <0.00%> (-0.44%) ⬇️
Tests/CocoaLumberjackTests/DDFileLoggerTests.m 95.10% <0.00%> (-0.26%) ⬇️
Tests/CocoaLumberjackTests/DDLogMessageTests.m 92.85% <0.00%> (-0.25%) ⬇️
Sources/CocoaLumberjack/DDASLLogger.m 0.00% <0.00%> (ø)
Sources/CocoaLumberjack/DDTTYLogger.m 0.00% <0.00%> (ø)
Sources/CocoaLumberjack/CLI/CLIColor.m 0.00% <0.00%> (ø)
Sources/CocoaLumberjack/DDASLLogCapture.m 0.00% <0.00%> (ø)
Tests/CocoaLumberjackTests/DDLogFileManagerTests.m 100.00% <0.00%> (ø)
... and 21 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 80ada1f...c3afb09. Read the comment docs.

@ffried
Copy link
Member

ffried commented Aug 27, 2021

@nhgrif Thanks for proposing and implementing this change!

For the rest of the team here:
I've already outlined on Stack Overflow that having custom log levels in Swift is currently non-trivial. It's probably even less trivial now on Objective-C, given that it's likely to check the NS_ENUM values as well.
Defining it as NS_OPTIONS would allow custom values. OSLog also uses a RawRepresentable struct in its new Swift version. So it's nothing entirely new. swift-log on the other hand uses an enum for its log levels.

I'd be somewhat in favor of it being defined as NS_OPTIONS. We shouldn't have to do much in our code base since we rarely switch over the values. We are just breaking source compatibility here, since others might switch and might need to have a default case now.

@nhgrif The easy part is done. 😉
I still see a few TODOs left here:

  • The build currently fails for CocoaLumberjackSwift
  • We probably need to adjust our swift-log backend as well - I can take on that if you like.
  • It seems fair to extend the documentation you mentioned in your Stack Overflow question with a Swift example

@ffried
Copy link
Member

ffried commented Aug 30, 2021

@nhgrif I just realized it should probably be NS_TYPED_EXTENSIBLE_ENUM instead of NS_OPTIONS. 👀
NS_OPTIONS is an OptionSet in Swift. However, a log message can only be logged with one level - not several levels.

This documentation shows the differences between the various options.

As discussed in [this StackOverflow question](https://stackoverflow.com/questions/68854372/how-to-implement-custom-log-levels-in-cocoalumberjack-from-swift), there's not really a clean way to implement custom log levels in Swift.

As `DDLogFlag` is defined as `NS_OPTIONS`, absolutely any value is valid here, but with `DDLogLevel` defined as an enum, as far as Swift as concerned the existing levels are the only valid levels.  I can't even particularly cleanly write aliases for the existing levels.

Further, to me, it doesn't even make particular sense for `DDLogFlag` to be `NS_OPTIONS` while `DDLogLevel` is `NS_ENUM`.  If anything, shouldn't it almost be the opposite...?  Logically, it doesn't make sense that something might be logged as `[.error, .info]` from Swift, but you could log something using that flag... but what does that even mean?  Meanwhile, from Swift, I can not do as some CocoaLumberjack documentation suggests, and easily filter to say "show me `.info` level, but not `.warnings`, but do show me `.error` level".  This again comes back to the fact that `DDLogLevel` is an enum and from the Swift side I can not create any custom values for this.

By this logic, `DDLogFlag` itself should arguably be `NS_ENUM` rather than `NS_OPTION`, however, I recommend leaving it as `NS_OPTION`, because changing it to `NS_ENUM` once again would limit my ability to use custom log levels from Swift.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants