Repository: cocotb/cocotb

Issue:
cocotb colorizer does not support custom logging levels
The attached file demonstrates that cocotb does not support custom logging levels. This may be the intention as there is an assertion in the code regarding acceptable logging levels, it is limiting. 

I don't think cocotb should throw an exception on an unexpected level. Instead I think it should have a default behavior. It appears the log colorization system doesn't know what to do with `5`. It likely needs a `try`/`except`.

```
Traceback (most recent call last):
  File "/Users/raysalemi/opt/anaconda3/lib/python3.8/logging/__init__.py", line 1081, in emit
    msg = self.format(record)
  File "/Users/raysalemi/opt/anaconda3/lib/python3.8/logging/__init__.py", line 925, in format
    return fmt.format(record)
  File "/Users/raysalemi/opt/anaconda3/lib/python3.8/site-packages/cocotb/log.py", line 251, in format
    msg = '\n'.join([SimColourLogFormatter.loglevel2colour[record.levelno] % line for line in msg.split('\n')])
  File "/Users/raysalemi/opt/anaconda3/lib/python3.8/site-packages/cocotb/log.py", line 251, in <listcomp>
    msg = '\n'.join([SimColourLogFormatter.loglevel2colour[record.levelno] % line for line in msg.split('\n')])
KeyError: 5
Call stack:
```
[bug_example.zip](https://github.com/cocotb/cocotb/files/5842227/bug_example.zip)






Discussion:
Does this mean you were able to solve #2359?

Either way, this is an obvious bug with a simple fix, thanks - changing `[record.levelno]` to `.get(record.levelno, "")` would fix it:
https://github.com/cocotb/cocotb/blob/26304cfc5fc9adbf567f2929910d5b6b9f414331/cocotb/log.py#L250-L253
I'm not sure yet. I'm still not seeing my 5 level messages, but I'm
thinking they must not be reaching cocotb's logger at all. I have
propagation set to False in mine.

On Wed, Jan 20, 2021 at 7:26 AM Eric Wieser <notifications@github.com>
wrote:

> Does this mean you were able to solve #2359
> <https://github.com/cocotb/cocotb/issues/2359>?
>
> Either way, this is an obvious bug with a simple fix, thanks!
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/cocotb/cocotb/issues/2362#issuecomment-763570696>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAYFXWR6KWQ5ZXHYJAJCVE3S23DXHANCNFSM4WKSMIIQ>
> .
>

> Does this mean you were able to solve #2359?
> 
> Either way, this is an obvious bug with a simple fix, thanks - changing `[record.levelno]` to `.get(record.levelno, "")` would fix it:
> 
> https://github.com/cocotb/cocotb/blob/26304cfc5fc9adbf567f2929910d5b6b9f414331/cocotb/log.py#L250-L253

That's a good idea.  I've just learned about `get()`
Would you be willing to make a PR with that change? It would be a good exercise in getting familiar with how PRs work on github, but if you don't want to I'm sure someone else will fix it soon.
I was thinking that myself.  I'm trying to learn about how GitHub works.

On Thu, Jan 21, 2021 at 9:51 AM Eric Wieser <notifications@github.com>
wrote:

> Would you be willing to make a PR with that change? It would be a good
> exercise in getting familiar with how PRs work on github, but if you don't
> want to I'm sure someone else will fix it soon.
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/cocotb/cocotb/issues/2362#issuecomment-764696157>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAYFXWSDRJ6NVUXMYZONLT3S3A5NVANCNFSM4WKSMIIQ>
> .
>

We do have instructions (with links) about contributing:, starting ~ here: https://github.com/cocotb/cocotb/blob/master/CONTRIBUTING.md#setting-up-a-development-environment

For the small change above, starting here may be enough: https://github.com/cocotb/cocotb/blob/master/CONTRIBUTING.md#how-to-get-changes-merged
I'd like to fix this. I'm not sure how to assign it to me.

I've tried setting up my environment but tox says it cannot find cocotb:

```
SIM=icarus TOPLEVEL_LANG=verilog tox -e py38-macos
Modelsim/Questa executable (vdbg) executable not found. No FLI interface will be available.
py38-macos develop-inst-noop: /Users/raysalemi/repos/cocotb
py38-macos installed: attrs==20.3.0,cocotb==1.5.0.dev250+gb49c16dd,coverage==5.4,iniconfig==1.1.1,packaging==20.9,pluggy==0.13.1,py==1.10.0,pyparsing==2.4.7,pytest==6.2.2,pytest-cov==2.11.1,toml==0.10.2,xunitparser==1.3.3
py38-macos run-test-pre: PYTHONHASHSEED='2961615516'
py38-macos run-test: commands[0] | pytest
============================================================================== test session starts ===============================================================================
platform darwin -- Python 3.8.3, pytest-6.2.2, py-1.10.0, pluggy-0.13.1 -- /Users/raysalemi/repos/cocotb/.tox/py38-macos/bin/python
cachedir: .tox/py38-macos/.pytest_cache
rootdir: /Users/raysalemi/repos/cocotb, configfile: setup.cfg, testpaths: tests/pytest, cocotb/utils.py, cocotb/binary.py, cocotb/_sim_versions.py
plugins: cov-2.11.1
collected 14 items / 4 errors / 10 selected

===================================================================================== ERRORS =====================================================================================
_______________________________________________________________ ERROR collecting tests/pytest/test_binary_value.py _______________________________________________________________
tests/pytest/test_binary_value.py:6: in <module>
    from cocotb.binary import BinaryValue, BinaryRepresentation
E   ModuleNotFoundError: No module named 'cocotb'
_______________________________________________________________ ERROR collecting tests/pytest/test_binary_value.py _______________________________________________________________
ImportError while importing test module '/Users/raysalemi/repos/cocotb/tests/pytest/test_binary_value.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
```

However it is right there:

```
(cocotb_dev) (base) raysalemi@WriteNow cocotb % pip list
Package    Version
---------- ----------------------
cocotb     1.5.0.dev250+gb49c16dd
pip        21.0.1
setuptools 41.2.0
```

So I'm at a loss.

Resolving patch:
diff --git a/cocotb/log.py b/cocotb/log.py
--- a/cocotb/log.py
+++ b/cocotb/log.py
@@ -248,8 +248,8 @@ def format(self, record):
         msg = record.getMessage()
 
         # Need to colour each line in case coloring is applied in the message
-        msg = '\n'.join([SimColourLogFormatter.loglevel2colour[record.levelno] % line for line in msg.split('\n')])
-        level = (SimColourLogFormatter.loglevel2colour[record.levelno] %
+        msg = '\n'.join([SimColourLogFormatter.loglevel2colour.get(record.levelno,"%s") % line for line in msg.split('\n')])
+        level = (SimColourLogFormatter.loglevel2colour.get(record.levelno, "%s") %
                  record.levelname.ljust(_LEVEL_CHARS))
 
         return self._format(level, record, msg, coloured=True)


Test patch:
diff --git a/tests/test_cases/test_cocotb/test_logging.py b/tests/test_cases/test_cocotb/test_logging.py
--- a/tests/test_cases/test_cocotb/test_logging.py
+++ b/tests/test_cases/test_cocotb/test_logging.py
@@ -75,3 +75,12 @@ async def test_logging_default_config(dut):
         # Restore pre-test configuration
         os.environ = os_environ_prev
         cocotb_log.level = log_level_prev
+
+
+@cocotb.test()
+async def test_custom_logging_levels(dut):
+    logging.basicConfig(level=logging.NOTSET)
+    logging.addLevelName(5, "SUPER_DEBUG")
+    logger = logging.getLogger("name")
+    logger.setLevel(5)
+    logger.log(5, "SUPER DEBUG MESSAGE!")