logging error messages using logging API on ConnectPort

Hi,

I’m trying to use the standard python ‘logging’ module (http://docs.python.org/library/logging.html) for logging error messages to a file on my ConnectPort device’s memory. I get this error message:

ImportError: No module named logging

Is the logging module part of the python package for DIA applications, and if not, is it possible to add extra modules and how?

Thanks

Hi avoinemt,

By default, the logging module is not part of the Dia framework. You can add the module to the Dia framework by adding it to a location it knows about.

For instance, I copied the logging module into the lib/ directory, so my source tree would look like /src/lib/logging/.

Then you can import it from a device/presentation/logger like: ‘import lib.logging as logging’, and use it normally afterwards. When you go to use ‘make.py’ on the configuration file, you can investigate that the dia.zip has a lib/logging/ directory populated with the modules you used.

Here is a incredibly basic device driver that I did this to, just to see what would happen:

imports

from devices.device_base import DeviceBase
from settings.settings_base import SettingsBase, Setting
from channels.channel_source_device_property import *

import lib.logging as logging

constants

exception classes

interface functions

classes

#Null device is meant for testing purposes only and serves as an example
#device

class LogDevice(DeviceBase):
“”"
This class extends one of our base classes and is intended as an
example of a concrete, example implementation, but it is not itself
meant to be included as part of our developer API. Please consult the
base class documentation for the API and the source code for this file
for an example implementation.

"""

def __init__(self, name, core_services):
    self.__name = name
    self.__core = core_services

    ## Settings Table Definition:
    settings_list = [
    ]

    ## Channel Properties Definition:
    property_list = [
    ]
                                        
    ## Initialize the Devicebase interface:
    DeviceBase.__init__(self, self.__name, self.__core,
                            settings_list, property_list)


## Functions which must be implemented to conform to the DeviceBase
## interface:

def apply_settings(self):
    SettingsBase.merge_settings(self)
    accepted, rejected, not_found = SettingsBase.verify_settings(self)

    SettingsBase.commit_settings(self, accepted)
    

    return (accepted, rejected, not_found)

def start(self):      
    log = logging.getLogger('Mylogger')        
    
    handler = logging.StreamHandler()
    log.addHandler(handler)
    
    log.warn('Hello, this is a test.')
    
    return True

def stop(self):
    
    return True

Hope this helps!
Max

mkotasek,

Thanks for the reply. I tried a slightly different solution that seems to work as well. I put the logging module files in a separate zip file and added the path to the zip on the sys.path.

I still have a problem with the logging.config module though; it requires a module named cPickle which doesn’t seem to be part of the standard DIA python distribution. I tried looking for the file but did not succeed. I probably could configure the logging programmatically, but I wish I could use the logging.config module along with a configuration file.

Is there a way to add cPickle to a Digi device?

Thanks.

cPickle as the name implies is a C module, and you will not be able to add it to a device.

Pickle is supported on the platform, though it will be slower, because it’s implemented in python, rather than C code. You’d have to perform the same tasks to add the module - add the file and any other dependencies you are missing. I don’t know if it requires modifications to logging to make sure it falls back on Pickle when cPickle isn’t available.

Hope this helps,
Max

Yes, the most straightforward way to get pickle, is to modify the import of cPickle with an import of pickle.

Some people don’t like to modify the library files. If that is the case, there is a somewhat hackish workaround. Prior to importing logging add the following code.

import pickle
import sys
sys.modules[‘cPickle’] = pickle

This will tell the Python interpreter that cPickle has already been imported somewhere, and point it at the Python based pickle implementation. Since they are compatible interfaces, the importing code won’t know the difference. Once logging imports cPickle, it will be added to its namespace and should work.

Thanks everyone for your useful answers.

I tried your suggestions and everything seems to work. I packaged the .py files from the standard python distribution into a zip file and inserted it on the sys.path before the dia.zip, otherwise it conflicts with an existing “logging” folder and python cannot find the module.

As a hint for other people who will want to try that, I had to add the following modules to make it work:

logging/init.py
logging/config.py
logging/handlers.py
ConfigParser.py
cPickle.py
glob.py
pickle.py
SocketServer.py
fnmatch.py

cPickle is not available so you have to trick python into taking the pickle module instead, so here’s the content of the cPickle file:

import sys, pickle
sys.modules[‘cPickle’] = pickle

Note however that pickle seems to be used only with the SocketHandler and I haven’t tested it so it might not work.

I still have some problems getting the logging.config.fileConfig() to work with a RotatingFileHandler. Coding the configuration by hand works though.

Hey All,

I’ve followed the thread so far and I am able to write to a logfile with my ConnectPort WAN 3G IA. Presently, I am writing to example.log using the code sample below.

Does anybody know why the messages aren’t printing out to the console (via a telnet session) but are logging to the file?

Also, the logs in the logfile are not formatting correctly. I’ve tried (with no success) to add ’
’ to put each event on a new line. Is it possible?

import logging
logging.basicConfig(filename=‘WEB/python/example.log’,level=logging.DEBUG)
logging.debug(‘This message should go to the log file’)
logging.info(‘So should this’)
logging.warning(‘And this, too’)

Thanks,
Sam