Logging

OOPNET allows for logging on different levels. logging.INFO provides basic information about what OOPNET is doing, while logging.DEBUG provides for detailed information.

To enable logging, you can either create your own logger and set the logging handlers as you please, or use logger provided by OOPNET. This logger uses a RotatingFileHandler and a StreamHandler. The RotatingFileHandler writes up to 5 MB of data to oopnet.log before rotating the logs. The default logging level is logging.INFO but this behaviour can be overruled.

To show logging functionality, we first have to import the necessary packages.

import os
import logging

import oopnet as on

Now, let’s start the logger:

logger = on.start_logger()

Note

The logger only has to be started once! Don’t put this function call in every part of your package/module! Below is also an example that describes, how to implement logging in the other parts of your program.

Next, we read the Poulakis model.

filename = os.path.join('data', 'Poulakis.inp')

net = on.Network.read(filename)

This leads to a log message in oopnet.logs and in the console:

Reading model from 'data/Poulakis.inp'

If you want more details, you can set the logging level to logging.DEBUG

logger.setLevel(logging.DEBUG)

Now, if we reread the Poulakis model, we will get way more information:

net = on.Network.read(filename)

And here are the log contents:

Reading model from 'data/Poulakis.inp'
Reading Curves
Reading Patterns
Reading Junctions section
Added 30 Junctions
Reading Reservoirs section
Added 1 Reservoirs
Reading Tanks section
Added 0 Tanks
Reading Pipes section
Added 50 Pipes
Reading Pumps section
Added 0 Pumps
Reading Valve section
Added 0 Valves
Reading demand section
Reading Options
Reading report settings
Reading times settings
Reading Controls
Reading Energy
Reading Rules
Reading status section
Reading mixing section
Reading quality section
Reading reactions
Reading sources section
Reading Emitters section
Reading title
Reading Coordinates section

Now, what if you had a function, that you think might fail and that you want to log? OOPNET provides a decorator for this purpose, logging_decorator(), that needs a logger passed to it.

First, let’s pretend that the logger has already been started in another part of you program and you want to add logging, to a different part of your program (i.e., you don’t have to declare logging handlers, that’s already taken care of). To do this, we simply have to get the logger:

logger = logging.getLogger('oopnet')

We will now use this logger to log a custom function. We want to log a function that tries to add a float and a string. After declaring the function, we call it and of course an exception is raised:

@on.logging_decorator(logger)
def do_some_crazy_things():
    a = 0
    for b in [0, 1, 2, 'a']:
        a += b
    return a

This results in the following logs:

Error raised by 'do_some_crazy_things'
Traceback (most recent call last):
  File "/home/***/oopnet/oopnet/utils/oopnet_logging.py", line 46, in wrapper
        return func(*args, **kwargs)
  File "/home/***/oopnet_refactor/examples/logs.py", line 21, in do_some_crazy_things
        a += b
TypeError: unsupported operand type(s) for +=: 'int' and 'str'
Traceback (most recent call last):
  File "/home/***/oopnet/examples/logs.py", line 25, in <module>
        do_some_crazy_things()
  File "/home/***/oopnet/oopnet/utils/oopnet_logging.py", line 46, in wrapper
        return func(*args, **kwargs)
  File "/home/***/oopnet/examples/logs.py", line 21, in do_some_crazy_things
        a += b
TypeError: unsupported operand type(s) for +=: 'int' and 'str'

Summary

import os
import logging

import oopnet as on

logger = on.start_logger()

filename = os.path.join('data', 'Poulakis.inp')

net = on.Network.read(filename)

logger.setLevel(logging.DEBUG)

net = on.Network.read(filename)

logger = logging.getLogger('oopnet')


@on.logging_decorator(logger)
def do_some_crazy_things():
    a = 0
    for b in [0, 1, 2, 'a']:
        a += b
    return a


do_some_crazy_things()