On Thu, 2010-07-22 at 18:01 +0200, Nikola Pajkovsky wrote:
How to write your reporter plugin
---------------------------------
This plugin receives the entire finished crash report and posts/reports
it somewhere (e.g. logs it, mails it, posts it on some web tool...)
You have to override these methods:
std::string Report(const map_crash_data_t& pCrashData,
const map_plugin_settings_t& pSettings,
const char *pArgs)
void SetSettings(const map_plugin_settings_t& pSettings);
- It is not a mandatory method.
Example of header plugin
------------------------
This peace of code shows what should be included, how-to inherit proper
s/peace/piece/, s/how-to/how to/
class and how-to set up storage for options loaded from
HelloWorld.conf
set up *storage* for options?
$ cat abrt-reporter-hello-world.h
#ifndef ABRT_REPORTER_HELLO_WORLD_H
#define ABRT_REPORTER_HELLO_WORLD_H
/*
* Included header depends on what you want to do.
Well, headers don't depend and what we do. The sentence is badly formed.
It can just be removed...
* If you want to build reporter you have to include
`reporter'.
* Others are analyzer.h, database.h and action.h
*/
#include <abrt/reporter.h>
class CHelloWorld : public CReporter
{
private:
/*
* In our tutorial we will have two options called OptionBool
* and PrintString. Daemon will load HelloWorld.conf and save them
* through SetSettings method
Not really. "Daemon will load HelloWorld.conf and pass it to our
SetSettings method in parsed form, allowing us to change options"
(that is, daemon does not save options. we do)
*/
bool m_OptionBool;
std::string m_PrintString;
public:
/**
* A method, which reports a crash report to particular receiver.
We use word "report" in too many meanings.
I propose s/crash report/crash dump/
* The plugin can takes arguments, but the plugin has to
parse them
"can take" w/o "s"
* by itself.
* @param pCrashData A crash report.
* @oaran pSettings A settings passed from gui or cli
* @param pArgs Plugin's arguments.
* @retun A message which can be displayed after a report is created.
*/
virtual std::string Report(const map_crash_data_t& pCrashData,
const map_plugin_settings_t& pSettings,
const char *pArgs);
/**
* A method, which takes a settings and apply them. It is not a mandatory
"takes settings"
* method.
* @param pSettings Plugin's settings
*/
virtual void SetSettings(const map_plugin_settings_t& pSettings);
};
#endif
Example of source code of plugin
--------------------------------
$ cat abrt-reporter-hello-world.cpp
#include <abrt/abrtlib.h>
#include <abrt/abrt_exception.h>
#include "abrt-reporter-hello-world.h"
std::string CHelloWorld::Report(const map_crash_data_t& pCrashData,
const map_plugin_settings_t& pSettings,
const char *pArgs)
{
if (!m_OptionBool)
{
/*
* Exceptions is used to notify gui/cli that something is wrong
* and stop reporting and gui/cli show error message.
"and stop reporting; gui/cli will show it as an error message"
*/
throw CABRTException(EXCEP_PLUGIN, "OptionBool is set to `no',
wrong");
}
/*
* Same as example above, but here is shown how you can use try..catch block
"but here we show how..."
*/
try
{
}
catch (CABRTException& e)
{
//throw CABRTException(EXCEP_PLUGIN, "Oops something wrong");
}
/*
* If you want to log some information use function log
Append period to the above line.
* abrtd can be started as standalone application running in
* foreground(abrtd -d) and then you will see log information.
^^ add space
* Logging has tree levels and they are controlled by VERBx
where `x'
* can be 1,2 and 3. If you want to level1(VERB1) run abrtd -dv,
"If yo want to see level1 (VERB1 messages) ..."
* for level2(VERB2) -dvv and for level3 -dvvv.
*/
VERB1 log("what you sometimes want to see, even on a production box");
VERB2 log("debug message, not going into insanely small details");
VERB3 log("lots and lots of details");
return m_PrintString;
}
/*
* Daemon looks into /etc/abrt/plugins and loads all configuration files
* inside directory which have set `Enable = yes' and call for each enabled
* plugins SetSettings.
Bad English.
*/
void CHelloWorld::SetSettings(const map_plugin_settings_t& pSettings)
{
m_pSettings = pSettings;
map_plugin_settings_t::const_iterator end = pSettings.end();
map_plugin_settings_t::const_iterator it;
it = pSettings.find("OptionBool");
if (it != end)
m_OptionBool = string_to_bool(it->second.c_str());
it = pSettings.find("PrintString");
if (it != end)
m_PrintString = it->second;
}
/*
* Use the macro PLUGIN_INFO in the *.cpp file of your plugin so that your
* subclass will be properly registered and treated as a plugin.
* This sets up all the lower-level and administrative details to fit your
* class into the plugin infrastructure. The syntax is:
*
* PLUGIN_INFO(type, plugin_class, name, version, description, email, www, gtk_builder)
* - "type" is one of ANALYZER, ACTION, REPORTER, or DATABASE
* - "plugin_class" is the identifier of the class
* - "name" is a string with the name of the plugin
* - "version" is a string with the version of the plugin
* - "description" is a string with the summary of what the plugin does
* - "email" and "www" are strings with the contact info for the
author
* - "gtk_builder" is path to plugins gui
*/
PLUGIN_INFO(REPORTER,
CHelloWorld,
"HelloWorld",
"0.0.1",
"Show `Hello world!!!' in gui",
"author",
"www adress to project/plugin",
"/path/to/gui.plugin")
Example of configuration file
-----------------------------
When option `Enabled` is missing or is set to `no', plugin won't be loaded
otherwise
options will be loaded, parsed and passed to plugin. Plugin has overrided function
called SetSettings which is responsible to store options into class.
When option 'Enabled' is missing or is set to 'no', plugin won't be
loaded
at abrtd start-up (but may be loaded later if plugin is used in one of the
directives). If it is set to 'yes', plugin is loaded right away.
At the plugin load time, options are parsed by daemon and passed to plugin's
SetSettings method.
$ cat HelloWorld.conf
Enabled = yes
# just for demonstration
# if OptionBool is set to yes it will be printed text in PrintString option
...set to yes, it will print the text specified in PrintString option
# if OptionBool is set to no it will be printed "OptionBool is
set to `no', wrong"
set to no, the error with the message "OptionBool is set to `no', wrong"
will be generated.
OptionBool = yes
PrintString = "Hello World!!!"
Example of Makefile
-------------------
Makefile is written to build plugin on 64bit machines. If you want to build for
32bit rid of -m64 in build section and rename /usr/lib64/abrt to /usr/lib/abrt
get rid
$ cat Makefile
PROGRAM = libHelloWorld
CXX = g++
SRCS += abrt-reporter-hello-world.cpp
OBJS += $(addsuffix .o, $(basename $(SRCS)))
.PHONY: clean install uninstall
%.o: %.cpp
$(CXX) `pkg-config --cflags --libs abrt` -m64 -c -Wall -std=c++98 -pedantic $<
$(PROGRAM).so: $(OBJS)
$(CXX) -shared $< -o $@
clean:
rm -f *.o *.so
install:
install -m 755 -D $(PROGRAM).so /usr/lib64/abrt/
install -m 644 -D HelloWorld.conf /etc/abrt/plugins/
uninstall:
rm -f /usr/lib64/abrt/$(PROGRAM).so
rm -f /etc/abrt/plugins/HelloWorld.conf
--
vda