Skip to content
This repository was archived by the owner on Sep 6, 2023. It is now read-only.

esp/modesp.c: Add osdebug() and oslog() #112

Closed
wants to merge 2 commits into from

Conversation

ak15199
Copy link
Contributor

@ak15199 ak15199 commented Jun 15, 2017

Code lineage:

osdebug() is based loosely on the version in esp8266, but there didn't
seem to be an obvious way of choosing a particular UART. The basic
behavior is the same, though: provide None, and logging is disabled;
provide an integer and logging is restored to the default level.

To build on that, and because the IDF provides more functionality, a
second parameter has now been implemented which allows the active log
level to be set:

esp.osdebug(uart[, level])

The module has a corresponding set of LOG_ values to set this
accordingly. An additional level esp.LOG_CRITICAL, which maps to
esp.LOG_ERROR has been included in order to provide better
symetry with standard Python logging frameworks.

In order to test out correct behavior, it was straightforward to add a
second function that calls the IDF to perform a logging operation:

esp.oslog(level, tag, message)

Because our intent to write anything in Python that can be in Python,
the thought is that format and parameters will be transformed to a
simple string in Python, to them be passed here for rendering.

Code lineage:

osdebug() is based loosely on the version in esp8266, but there didn't
seem to be an obvious way of choosing a particular UART. The basic
behavior is the same, though: provide None, and logging is disabled;
provide an integer and logging is restored to the default level.

To build on that, and because the IDF provides more functionality, a
second parameter has now been implemented which allows the active log
level to be set:

   esp.osdebug(uart[, level])

The module has a corresponding set of LOG_ values to set this
accordingly. An additional level esp.LOG_CRITICAL, which maps to
esp.LOG_ERROR has been included in order to provide better
symetry with standard Python logging frameworks.

In order to test out correct behavior, it was straightforward to add a
second function that calls the IDF to perform a logging operation:

   esp.oslog(level, tag, message)

Because our intent to write anything in Python that can be in Python,
the thought is that format and parameters will be transformed to a
simple string in Python, to them be passed here for rendering.
@ak15199
Copy link
Contributor Author

ak15199 commented Jun 15, 2017

I wanted to be able to switch off logging to the console, and was disappointed to see esp.osdebug() missing. I mean, esp32 is an evolving platform, so it's totally fair, but I still wanted it.

There are a couple of other things that I want to work on, but this one seemed like relatively low hanging fruit that I could use to learn the platform. Hopefully I haven't made too many rookie mistakes along the way, and that I've observed style guidelines and pull request convention, but let me know if I need to do anything differently in the future.


return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_osdebug_obj, 1, 2, esp_osdebug);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to have this function just take 1 arg, esp.osdebug(level), same as esp8266, and just have level=None mean disable, and any other value is an integer that is passed as the second arg to esp_log_level_set?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case of the ESP32 it doesn't really allow you to redirect errors to different UARTs (?) so I'd say it's fine to repurpose the single argument to this function to be the log level.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe? You're the maintainer, so get the final say.

The reasoning for the additional parameter is twofold: that repurposing the existing argument would break backwards compatibility for anyone migrating code from ESP8266 in a minor but unpredictable way; the other is that although I can't see how to do it yet, the ESP32 does have two UARTs, and the hardware allows developers to change pin assignments for how UARTs are routed... it may be that at some point this would become possible.

But would appreciate your thoughts.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, points taken. But I think the implementation should be adjusted so that passing None as the first arg always disables logging, even if there are 2 args passed (eg esp.osdebug(None, 123)).

esp32/modesp.c Outdated

return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_oslog_obj, esp_oslog);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a neat function, but is it useful? What was your use case for it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Python you can just use "print" to write logging info, or use the logging module (which is already ported to MicroPython).

Copy link
Contributor Author

@ak15199 ak15199 Jun 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right... there are other ways of delivering text. I think that use cases for print and logging are different though. I like the way that (regular) Python at least allows for different types of endpoints. If the endpoint is the console, then it occurred to me (after I'd added the thing for testing) that it might be less jarring to present log output in a manner consistent with the OS (in terms of tags, colors, and so on).

(so basically a shim between the python logging module and the OS)

Again, though, I'll leave you to decide.

esp32/modesp.c Outdated
{ MP_OBJ_NEW_QSTR(MP_QSTR_LOG_DEBUG), MP_OBJ_NEW_SMALL_INT((mp_uint_t)ESP_LOG_DEBUG)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_LOG_VERBOSE), MP_OBJ_NEW_SMALL_INT((mp_uint_t)ESP_LOG_VERBOSE)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_LOG_DEFAULT), MP_OBJ_NEW_SMALL_INT((mp_uint_t)LOG_LOCAL_LEVEL)},
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to have this protected by MODESP_INCLUDE_CONSTANTS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That did seem a bit weird. Thanks for the pointer.

esp32/modesp.c Outdated

#if MODESP_INCLUDE_CONSTANTS
{ MP_OBJ_NEW_QSTR(MP_QSTR_LOG_NONE), MP_OBJ_NEW_SMALL_INT((mp_uint_t)ESP_LOG_NONE)},
{ MP_OBJ_NEW_QSTR(MP_QSTR_LOG_CRITICAL), MP_OBJ_NEW_SMALL_INT((mp_uint_t)ESP_LOG_ERROR)},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be ESP_LOG_CRITICAL?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The levels are defined as an enum and typedef in esp-idf/components/log/include/esp_log.h, and there isn't a ESP_LOG_CRITICAL. I wanted to provide some equivalence for the Python abstraction, though: the absence of the level in the base OS, shouldn't be something that your casual developer needs to worry about.

esp32/modesp.c Outdated
@@ -101,6 +146,17 @@ STATIC const mp_rom_map_elem_t esp_module_globals_table[] = {

{ MP_ROM_QSTR(MP_QSTR_neopixel_write), MP_ROM_PTR(&esp_neopixel_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_dht_readinto), MP_ROM_PTR(&dht_readinto_obj) },

#if MODESP_INCLUDE_CONSTANTS
{ MP_OBJ_NEW_QSTR(MP_QSTR_LOG_NONE), MP_OBJ_NEW_SMALL_INT((mp_uint_t)ESP_LOG_NONE)},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use MP_ROM_QSTR and MP_ROM_INT for the macro wrappers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thank you!

@dpgeorge
Copy link
Member

I reviewed the code before reading the above comments, sorry!

An additional level esp.LOG_CRITICAL, which maps to
esp.LOG_ERROR has been included in order to provide better
symetry with standard Python logging frameworks.

IMO this is not necessary. The less constants in the esp module the better.

Because our intent to write anything in Python that can be in Python,
the thought is that format and parameters will be transformed to a
simple string in Python, to them be passed here for rendering.

With that philosophy (which is a good philosophy) one should use the Python logging module, not have something extra like oslog.

@dpgeorge
Copy link
Member

I wanted to be able to switch off logging to the console, and was disappointed to see esp.osdebug() missing. I mean, esp32 is an evolving platform, so it's totally fair, but I still wanted it.

Yes, I agree, the info messages can get annoying (not to mention mess up scripts/tests that don't expect them). So the addition of esp.osdebug is certainly welcome, thanks!

@ak15199
Copy link
Contributor Author

ak15199 commented Jun 17, 2017

I just commented on your original comments before I saw your latest messages. Unless I hear otherwise, I'll remove oslog from the pull request. Thanks for your attention, Damien!

@dpgeorge dpgeorge mentioned this pull request Oct 4, 2017
@dpgeorge
Copy link
Member

This PR was reworked a little to make esp.osdebug(None) always disable the log even if a second arg is given, and then merged in 84035f0

Thanks @ak15199 for the contribution.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants