|
| 1 | +# Development Log: 20210415 |
| 2 | + |
| 3 | +This log covers the implementation of the following: |
| 4 | + |
| 5 | +- Adding support so that users can add log statements during an interrupt |
| 6 | +- Adding the ability to specify the allowed log level on a per-module basis |
| 7 | +- Implementing a Teensy logging strategy that allows for an EEPROM or circular buffer fallback if the SD card is not present |
| 8 | + |
| 9 | +## Interrupt Logging |
| 10 | + |
| 11 | +We received this request: |
| 12 | + |
| 13 | +> Would like to be able to add an entry into the log during interrupt routines. The current circular memory queued buffer works fine for that, however default library behavior to initiate a write when that circular buffer happens to be full is a problem if we are in an interrupt routine. Looking for a change which would set it into a state where an overrun condition would be created which could then be later logged by the main loop (which is also where we would control the flush timing). |
| 14 | + |
| 15 | +- Deleted `LOG_LEVEL_INTERRUPT_PREFIX` definition because this is unused in the code. Doesn't actually need to be used for our interrupt solution. |
| 16 | +- Setting will be configured via a simple boolean flag |
| 17 | +- We'll need a function to control the setting. That should return the previously configured value so that we can restore it later. |
| 18 | +- We'll add a new loginterrupt() call that will automatically disable the setting under the hood, log the data, and restore the setting |
| 19 | + - This means the user still must manually flush outside of interrupt context |
| 20 | + - Print echoing should also be disabled! |
| 21 | +- We need to add some way to log an overrun condition |
| 22 | + |
| 23 | +Refactoring was required: I needed to move flush behavior into the base class if we're giong to control this through general APIs, rather than duplicating beahvior throughout the strategies. I also disabled auto-flush by default for the circular buffer strategies. |
| 24 | + |
| 25 | +## Per-Module Log Level |
| 26 | + |
| 27 | +We received this request: |
| 28 | + |
| 29 | +> We have multiple major subsystems and if we turn on Debugging level for all of them the data becomes overwhelming and pretty useless. We could give each subsystem its own log file but then correlating events across them becomes a problem. Would be interested in an enhancement where logging level could be set by subsystem. |
| 30 | + |
| 31 | +The challenge here is that we need to support two cases: people who want to specify a module, and people who don't! |
| 32 | + |
| 33 | +First, I tried propagating this through the base class using templates. This caused multiple problems: |
| 34 | + |
| 35 | +- Now every strategy has to be aware of the base class template parameter |
| 36 | +- You have to propagate the module template param upward if you want that to be available in your strategy |
| 37 | +- People can only use the default setting like this: AVRCicularLogBuffer<>, which probably isn't ideal for Arduino users |
| 38 | +- There is an explosion in interfaces: you need to duplicate all the log-level calls for taking a module ID and not. |
| 39 | + |
| 40 | +Rather than doing all of that, I chose to isolate the implementation in a new strategy. This limits the complexity to a single place. Users can opt-in by simply making a strategy that supplies that behavior. |
| 41 | + |
| 42 | +## Fallback Strategy |
| 43 | + |
| 44 | +We received this question: |
| 45 | + |
| 46 | +> How would I write startup code so that if I don't find an SD card I basically then instead instantiate a circular memory buffer log? Or I might implement an eeprom log on a teensy 3.5. |
| 47 | +> So essentially want to fallback to a smaller eeprom storage log, likely with a different log level. |
| 48 | +> Can I do that with startup code and have the main line log calls remain the same? |
| 49 | + |
| 50 | +Here's what is required: |
| 51 | + |
| 52 | +1. Adding function overrides to begin() that can be used to initialize the logger with alternative implementations (e.g., an EEPROM object, or no arguments to stick to the underlying circular buffer only) |
| 53 | +2. You will need to store a pointer to the new interface objects inside of the logger strategy class |
| 54 | +3. flush() needs to be updated to handle multiple paths. I would personally tackle this |
| 55 | +4. size() needs to be updated to handle alternative approaches (e.g., right now it only returns file_.size(), but if you have no SD card you have no file_ object initialized) |
| 56 | +5. capacity() needs to be updated to handle alternative approaches |
| 57 | +6. In the startup code, you initialize the necessary components, and then programmatically decide which version of begin() to call. |
0 commit comments