Logger - Lua plugin to speed up troubleshooting

Hi fellow developers!

We have just released a new plugin, Logger. 

https://marketplace.coronalabs.com/plugin/logger

In short Logger is created to help and speed up troubleshooting corona applications. 

Before logger we had log files looking like this:

09:45:11.557     : loading

09:45:11.563     : beforeInitiAds

09:45:11.600     : afterInitAds

09:45:12.601     : before init purchases

09:45:12.622     : has init purchases true

09:45:12.651     : after init purchases

09:45:12.517     : load state

09:45:12.520     : state loaded

09:45:12.520     : state is now set

09:45:12.521     : start timer

09:45:12.522     : 1

09:45:12.522     : 2

and so on… the above logs are both excessive and unclear. 

With Logger the logs are cleaner, tells you where in code it is called and gives you a good overview just by glancing at the log tag  / channel, eg. [main]

03:18:11.712 /LOG:   [main] Initializing analytics  (main.lua:143)

03:18:11.712 /LOG:   [state] initialize state  (lib/configuration/state.lua:init:123)

03:18:11.726 /LOG:   [crosspromo] init  (lib/crosspromo/CrossPromo.lua:init:195)

03:18:11.726 /DEBUG:   [crosspromo] Initializing Cross promo for store google  (lib/crosspromo/CrossPromo.lua:init:197)

03:18:11.726 /LOG:   [crosspromo] Cross promo data loaded successfully  (lib/crosspromo/CrossPromo.lua:loadCrossPromoData:165)

03:18:11.726 /DUMP:   [state] [xp_download_time] 1485958687  (lib/configuration/state.lua:get:102)

So what did we achieve:

  1. We see exactly where we are in source code
  2. The channel / tag of each log message provides clear information about what the message is related to
  3.  Log messages can be filtered based on channel and log level, eg. in the example above we have filtered out DEBUG and DUMP for channel [main]. This makes is A LOT easier to troubleshoot specific issues.

Among the list of features

  • See where in code the log statement is made, eg. path, file, function and line in file.

  • Setup log channels / tags - This allows filtering of log messages depending on what you are interested at this time and a much clearer log where you can easily see what the log message is related

  • Write to console with the following log levels: Error, Warning, Log, Debug, Dump

  • Highlight warnings / errors

  • Use different log setups for simulator, device, etc. 

  • Log complex messages like multiple arguments, tables, etc. etc.

Quick start

  • build.settings - Include the plugin in build settings 
    • [‘plugin.logger’] = {publisherId = 'com.yogergames’},
  • initialize
    • local logger = require(“plugin.logger”)
    • local logOptions = {}
    • logOptions.highlight_errors = true
    • logOptions.highlight_warnings = true
    • logOptions.log_levels = {
    •     global = logger.LEVELS.WARNING, – Will set log level WARNING for GLOBAL channel
    •     main = logger.LEVELS.DUMP
    • }
    • logger.init(logOptions)
  • start logging
    • logger.error(“main”, “print an error from channel main”)
    • logger.warning(“main”, "print a warning from channel main”)
    • logger.log(“main”, "print a log message from channel main”)
    • logger.debug(“main”, "print a debug message from channel main”)
    • logger.dump(“main”, “print a dump message from channel main”)

Initially the plugin will be free.

If you have any questions, feel free to send a message or write below.

You can also send us an email at support@yogergames.com

More detailed docs can be found at https://yogergames.gitlab.io/logger/

When Joakim approached me to ask for beta-testing of the Logger I jumped at the opportunity. I’ll try to return the favor by explaining why and how Logger helps me save time every day.

I have a bunch of different ‘subsystems’ in my code, and I used to have generic print statements tracking the flow through the app. When something was buggy, I would add some temporary but verbose print statements to figure out the issue. I’d sometimes note in the log message roughly where I was in the code, e.g. “IAP, restore(): success”. But more often than not the log message would be a short temp note like “restore ok”.

Then, once I’d sorted out the issue, one of three things would inevitably happen to those debut printouts

  1. I’d comment them out
  2. I’d delete them
  3. I’d forget they were there

In scenarios 1 and 2, this meant that if, or rather when , I had bugs in that subsystem later on, I’d have to go back and uncomment or restore the printouts. In scenario 3 (forgetting them) my logging was cluttered so I sometimes missed other important log messages in addition to exposing potentially sensitive details to the end user.

So, enter the Logger. The value of the Logger comes from the way it lets you  structure , prioritize and toggle  your logging, while providing the at-a-glance details you need in order to act on your logging: Where things happen (file, method and line number) and how important they are.

For example, you structure your logging by defining suitable channels, grouping by code functionality or subsystem. E.g. I think I have “IAP”, “Ads”, “State”, “CrossPromo”, “Analytics” and a few more. Then you go through the current logging, assigning them to the appropriate channel while also deciding how important the messages are:

  • Useful basic stuff, like package name and market build, that should always be shown? Use “log” level/severity
  • Stuff that you as a developer always want to see, but too much detail for regular user? Use “debug” level
  • Detailed / verbose logging that you only want to see if you are digging into a particular part of the code? Use “dump” level
  • Things that aren’t that good, and you as a dev need to notice them, but the code will still work? E.g. fail to download a remote config file. Use “warning” level
  • Errors which aren’t quite so bad that you want to go down in flames, but still super-important to notice when testing? Use “error” level

And once you’ve done this (in all of 30 minutes or so), you never need to remove any of your logging statements! You just toggle on and off what you want to see, and at which level of detail, depending on the situation:

  • Testing on device? Programmatically enable “debug” log level on your own devices (based on device id), while normal users only see the basic log level
  • Debugging dodgy ad code? Show only the “Ads” channel, and enable the “dump” log level, where you log copious amounts of ad network response details.
  • Daily work? Let the Logger print all channels on the “debug” log level, and pick up on warnings and errors (that you have defined) thanks to the highlighting feature

Hope that helps clarify the core usefulness of Logger.

NB: If you’ve done any native development on Android, you’ll see that the way Logger works mimics the Android Java Log class: http://stackoverflow.com/questions/8176220/whats-the-console-log-of-java . Super-useful stuff

@YogerGames - What a great idea.  I built my own system to do this but it is super-clunky and relies on a lot of if’s:

if (reports.graphics == true) then print(“graphic x loaded”) end

and requires that I maintain an extensive reports table.  I’m looking at your API’s now and they look much more orderly than my methods.  Thanks for sharing this with the community.

Jonathan

Thanks Jonathan! 

Let me know if you see something weird, strange, problematic! 

/Joakim

It was a while ago I updated the plugin. Any feature suggestions?

The plugin won’t activate in the marketplace

Hi,

I don’t know the reason for this but I suspect it is an issue with the marketplace.