Customizing C++ CAF framework - c++

My question is about the possibility of customizing the logging/tracing done by CAF - viz. does the C++ CAF framework allow an application linking with it to customize the logging & tracing done within CAF?
For e.g., CAF writes its logs to log file if logging is enabled during compilation. But if an application wished to integrate the logs/traces generated by CAF with its own logging mechanism(syslog etc), is there any hook provided by CAF to do that?
I went through the CAF logger class, but could not see any such mechanism - the CAF logger class is not derivable, and the set_current_logger() method takes a logger* as input, etc.
Any pointers on how to achieve the above requirement would be appreciated.
Thanks.

is there any hook provided by CAF to do that?
Currently not.
The set_current_logger function merely sets a thread-local pointer to the actor system logger. However, CAF is very modular and allowing custom logger implementations is actually quite straightforward. I've created a feature request for this on the official GitHub repository. Stay tuned.

Related

mocking a class used by a Gradle plugin when testing

I'm writing a Gradle plugin that interacts with an external HTTP API. This interaction is handled by a single class (let's call it ApiClient). I'm writing some high-level tests that use Gradle TestKit to simulate an entire build that uses the plugin, but I obviously don't want them to actually hit the API. Instead, I'd like to mock ApiClient and check that its methods have been called with the appropriate arguments, but I'm not sure how to actually inject the mocked version into the plugin. The plugin is instantiated somewhere deep within Gradle, and gets applied to the project being executed using its void apply(Project project) method, so there doesn't appear to be a way to inject a MockApiClient object.
Perhaps one way is to manually instantiate a Project, apply() the plugin to it (at which point, I can inject the mocked object because I have control over plugin instantiation), and then programmatically execute a task on the project, but how can I do that? I've read the Gradle API documentation and haven't seen an obvious way.
A worst-case solution will be to pass in a debug flag through the plugin extension configuration, which the plugin will then use to determine whether it should use the real ApiClient or a mock (which would print some easily grep-able messages to the STDOUT). This isn't ideal, though, since it's more fuzzy than checking the arguments actually passed to the ApiClient methods.
Perhaps you could split your plugin into a few different plugins
my-plugin-common - All the common stuff
my-plugin-real-services - Adds the "real" services to the model (eg RealApiClient)
my-plugin-mock-services - Adds "mock" services to the model (eg MockApiClient)
my-plugin - Applies my-plugin-real-services and my-plugin-common
my-plugin-mock - Applies my-plugin-mock-services and my-plugin-common
In the real world, people will only ever apply: 'my-plugin'
For testing you could apply: 'my-plugin-mock'

Is it OK to log from a Flask Extension?

I was looking at source from the Flask Extension Registry. I probably looked at about 6 or 7 projects and couldn't find any of them logging output.
My question is: is it OK to do so? If so, should I use app.logger or my own logger?
Yes, you should log - no, you should not use the application logger since the user will not the be able to configure your extension's logging verbosity separately from their own.
Instead, create your own logger using Python's built-in logging module. Add a NullHandler (Python 3 has one, create your own NullHandler for Python2) so that by default your library will not log anything. Add a documentation section explaining how the user can access your logger to setup handlers (and explicitly configure levels, should they so desire).
As is often the case, there is some very good advice on this subject in Python's documentation:
Configuring Logging for a Library
When developing a library which uses logging, you should take care to document how the library uses logging - for example, the names of loggers used. Some consideration also needs to be given to its logging configuration. If the using application does not use logging, and library code makes logging calls, then (as described in the previous section) events of severity WARNING and greater will be printed to sys.stderr. This is regarded as the best default behaviour.
If for some reason you don’t want these messages printed in the absence of any logging configuration, you can attach a do-nothing handler to the top-level logger for your library. This avoids the message being printed, since a handler will be always be found for the library’s events: it just doesn’t produce any output. If the library user configures logging for application use, presumably that configuration will add some handlers, and if levels are suitably configured then logging calls made in library code will send output to those handlers, as normal.

Catching system events in C Linux

I am writing an application on Linux which requires me to catch system events like:
System reboot
User 'xyz' logs in
'xyz' application crashes etc.
and need to execute some functionality based on that. For e.g.:
Run backup script
Run recovery program etc.
Can anyone please tell me how to catch system events in C/Linux ?
P.S: I am not talking about 'file system' events here :P
There is no concept of "system event". You need to specify which events you need to handle and implement appropriate mechanism for handling each:
System startup: The init process calls scripts from /etc/init.d during startup. The exact infrastructure differs slightly between distributions, but Linux Standards Base System Initialization should generally work on all.
User login/logout: The LSB also defines interface to the Pluggable Authentication Modules library. You can implement a shared library that will be called during login (and also other actions that require authentication and authorization). Depending on what you want to do there may already be a module that will work for you, so try looking for it first. In either case I don't think there is distribution-independent way of installing it and even on given distribution you have to consider that administrator might have made custom modification, so the installation will need manual intervention by the administrator.
Application crashes: You would have to instrument it.
I think you should consider reading systems logs - everything you ask about is logged to the syslog (for standard configuration). If your system uses syslog-ng, then you could even configure it to write directly to your program, see http://www.syslog.org/syslog-ng/v2/#id2536904 for details. But even with any other syslog daemon, you can always read file (or files) from /var/log just like tail -f does, end react on particular messages.
I'm not sure about catching application crashes - there's a kernel option to log every SIGSEGV in user processes, but AFAIK it is available only on ARM architecture - last resort would be to instrument your application (as Jan Hudec pointed out) to log something to syslog.

Logging for multi=threaded server component

I have a multi-threaded sever application that I'm writing in C++ and I need to implement a good and fairly efficient logging system. By efficient I mean that whatever amount of logging is configured, the application shouldn't ever come to a grinding halt. So preferably there is some thread that is dedicated to writing it's log files.
I want to log each request that the server component handles in it's own file, having a rotation system that removes files older then some threshold. A request is handled by 2 threads, one that does some conversion work and the a worker-thread that is part of thread pool (BOOST threadpool) that does all the other actions (database gets, calculations, etc). So the logging need be threadsafe and I have to be able to configure it for levels and let each Logger class instance (my own logger that implements some library) accept a new file name. So that each new Logger instance is created for a specific request.
My ultimate question is: Which logging library allows me to have a new Log file for each request and allows me to configure log levels? (IE: error, warning, critical, etc)
Or should I implement everything myself? (no logging is not an option)
I have looked at Boost::Logging v2 and since the main logger object, that holds all state (levels, files) is global, I cannot change the files for each request.
I have looked at templog.org and this I can't even get to compile. No matter what I include or which references I set, it can never find the templog namespace or any of its classes.
Have a look at Apache log4cxx. It a great logging library !

Error handling / error logging in C++ for library/app combo

I've encountered the following problem pattern frequently over the years:
I'm writing complex code for a package comprised of a standalone application and also a library version of the core that people can use from inside other apps.
Both our own app and presumably ones that users create with the core library are likely to be run both in batch mode (off-line, scripted, remote, and/or from command line), as well as interactively.
The library/app takes complex and large runtime input and there may be a variety of error-like outputs including severe error messages, input syntax warnings, status messages, and run statistics. Note that these are all incidental outputs, not the primary purpose of the application which would be displayed or saved elsewhere and using different methods.
Some of these (probably only the very severe ones) might require a dialog box if run interactively; but it needs to log without stalling for user input if run in batch mode; and if run as a library the client program obviously wants to intercept and/or examine the errors as they occur.
It all needs to be cross-platform: Linux, Windows, OSX. And we want the solution to not be weird on any platform. For example, output to stderr is fine for Linux, but won't work on Windows when linked to a GUI app.
Client programs of the library may create multiple instances of the main class, and it would be nice if the client app could distinguish a separate error stream with each instance.
Let's assume everybody agrees it's good enough for the library methods to log errors via a simple call (error code and/or severity, then printf-like arguments giving an error message). The contentious part is how this is recorded or retrieved by the client app.
I've done this many times over the years, and am never fully satisfied with the solution. Furthermore, it's the kind of subproblem that's actually not very important to users (they want to see the error log if something goes wrong, but they don't really care about our technique for implementing it), but the topic gets the programmers fired up and they invariably waste inordinate time on this detail and are never quite happy.
Anybody have any wisdom for how to integrate this functionality into a C++ API, or is there an accepted paradigm or a good open source solution (not GPL, please, I'd like a solution I can use in commercial closed apps as well as OSS projects)?
We use Apache's Log4cxx for logging which isn't perfect, but provides a lot of infrastructure and a consistent approach across projects. I believe it is cross-platform, though we only use it on Windows.
It provides for run time configuration via an ini file which allows you to control how the log file is output, and you could write your own appenders if you want specific behaviour (e.g. an error dialog under the UI).
If clients of your library also adopt it then it would integrate their logging output into the same log file(s).
Differentiation between instances of the main class could be supported using the nested diagnostic context (NDC) feature.
Log4Cxx should work for you. You need to implement a provider that allows the library user to catch the log output in callbacks. The library would export a function to install the callbacks. That function should, behind the scenes, reconfigure log4cxxx to get rid of all appenders and set up the "custom" appender.
Of course, the library user has an option to not install the callbacks and use log4cxx as is.