I know how to setup logging targets in a Device Server from a DevProxy.
I may have missed it but I have not seen if that can be done from Server code itself - so that a Device Server can control its own logging!
I know how to setup logging targets in a Device Server from a DevProxy.
I may have missed it but I have not seen if that can be done from Server code itself - so that a Device Server can control its own logging!
Hi BrianMc
Good question. It appear to be possible, although not documented. You can use the tango.Logging
class to access these kind of things. You can also access the logger instance using self.get_logger()
, which gives you access to methods like get_level
and set_level
.
Code for TestLogDS.py:
#!/usr/bin/env python
from tango import Logging
from tango.server import Device, command
class TestLog(Device):
@command(dtype_in=str)
def custom_add_logging_target(self, target):
Logging.add_logging_target([self.get_name(), target])
self.info_stream("Added logging target %s", target)
Run it (without a database):
python -m tango.test_context TestLogDS.TestLog --host 127.0.0.1
Example of usage from ipython:
In [1]: import tango
In [2]: dp = tango.DeviceProxy('tango://127.0.0.1:8888/test/nodb/testlog#dbase=no')
In [3]: dp.get_logging_target()
Out[3]: ['console::cout']
In [4]: dp.custom_add_logging_target("file::/tmp/example.log")
In [5]: dp.get_logging_target()
Out[5]: ['console::cout', 'file::/tmp/example.log']
In [6]: !cat /tmp/example.log
<log4j:event logger="test/nodb/testlog" timestamp="1576566408757" level="INFO" thread="140388446758656">
<log4j:message><![CDATA[Added logging target file::/tmp/example.log]]></log4j:message>
<log4j:NDC><![CDATA[]]></log4j:NDC>
</log4j:event>
In [7]: dir(tango.Logging) # to show what methods are available
Out[7]:
['__class__',
'__delattr__',
'__dict__',
'__doc__',
'__format__',
'__getattribute__',
'__hash__',
'__init__',
'__module__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'add_logging_target',
'get_core_logger',
'remove_logging_target',
'start_logging',
'stop_logging']
Looks like that gives us access to this underlying C++ code:
Many thanks for the very helpful looking reply - I will follow it in more detail!