24 #include <gui_utils/logview.h>
25 #include <gui_utils/connection_dispatcher.h>
26 #include <netcomm/fawkes/client.h>
27 #include <logging/network.h>
56 LogView::LogView(
const char *hostname,
unsigned short int port)
67 LogView::LogView(BaseObjectType* cobject,
68 const Glib::RefPtr<Gtk::Builder> &builder)
69 : Gtk::TreeView(cobject)
84 delete __connection_dispatcher;
90 LogView::ctor(
const char *hostname,
unsigned short int port)
92 __list = Gtk::ListStore::create(__record);
94 __have_recently_added_path =
false;
96 __list->signal_row_inserted().connect(sigc::mem_fun(*
this, &LogView::on_row_inserted));
97 get_selection()->set_mode(Gtk::SELECTION_NONE);
99 if ( (hostname != NULL) && (port != 0) ) {
100 __connection_dispatcher =
103 __connection_dispatcher =
new ConnectionDispatcher(FAWKES_CID_NETWORKLOGGER);
106 append_column(
"Level", __record.loglevel);
107 append_column(
"Time", __record.time);
108 int compcol = append_column(
"Component", __record.component);
109 int msgcol = append_column(
"Message", __record.message);
116 Glib::ListHandle<Gtk::TreeViewColumn *> columns = get_columns();
118 for (Glib::ListHandle<Gtk::TreeViewColumn *>::iterator c = columns.begin();
123 #if GTK_VERSION_GE(3,0)
124 Gtk::CellRenderer *cell_renderer = (*c)->get_first_cell();
126 Gtk::CellRenderer *cell_renderer = (*c)->get_first_cell_renderer();
128 Gtk::CellRendererText *text_renderer =
129 dynamic_cast<Gtk::CellRendererText *
>(cell_renderer);
130 if ( text_renderer ) {
131 #ifdef GLIBMM_PROPERTIES_ENABLED
132 if ( (colnum == compcol) || (colnum == msgcol) ) {
133 (*c)->set_resizable();
135 if ( colnum == compcol ) {
136 text_renderer->property_ellipsize().set_value(Pango::ELLIPSIZE_END);
139 (*c)->add_attribute(text_renderer->property_background_gdk(), __record.background);
140 (*c)->add_attribute(text_renderer->property_foreground_gdk(), __record.foreground);
142 (*c)->add_attribute(*text_renderer,
"background-gdk", __record.background);
143 (*c)->add_attribute(*text_renderer,
"foreground-gdk", __record.background);
148 __connection_dispatcher->
signal_message_received().connect(sigc::mem_fun(*
this, &LogView::on_message_received));
149 __connection_dispatcher->
signal_connected().connect(sigc::mem_fun(*
this, &LogView::on_client_connected));
150 __connection_dispatcher->
signal_disconnected().connect(sigc::mem_fun(*
this, &LogView::on_client_disconnected));
151 #if GTK_VERSION_LT(3,0)
152 signal_expose_event().connect_notify(sigc::mem_fun(*
this, &LogView::on_expose_notify));
194 return __connection_dispatcher;
211 LogView::on_row_inserted(
const Gtk::TreeModel::Path& path,
212 const Gtk::TreeModel::iterator& iter)
214 Gtk::TreeModel::Path vstart, vend;
215 Gtk::TreeModel::Path prev = path;
216 get_visible_range(vstart, vend);
218 if (! get_visible_range(vstart, vend) ||
221 (__have_recently_added_path && (__recently_added_path == prev)))) ) {
227 __have_recently_added_path =
true;
228 __recently_added_path = path;
232 #if GTK_VERSION_GE(3,0)
234 LogView::on_draw(
const Cairo::RefPtr<Cairo::Context> &cr)
236 __have_recently_added_path =
false;
237 return Gtk::TreeView::on_draw(cr);
241 LogView::on_expose_notify(GdkEventExpose *event)
243 __have_recently_added_path =
false;
249 LogView::on_client_connected()
251 FawkesNetworkClient *c = __connection_dispatcher->
get_client();
252 if (c && c->connected()) {
253 FawkesNetworkMessage *msg =
new FawkesNetworkMessage(FAWKES_CID_NETWORKLOGGER,
257 gettimeofday(&t, NULL);
263 LogView::on_client_disconnected()
266 gettimeofday(&t, NULL);
280 const char *component,
bool is_exception,
283 const char *loglevel;
287 bool set_foreground =
false;
288 bool set_background =
false;
290 switch ( log_level ) {
293 color.set_rgb_p(0.4, 0.4, 0.4);
294 set_foreground =
true;
301 color.set_rgb_p(1.0, 1.0, 0.7);
302 set_background =
true;
306 color.set_rgb_p(1.0, 0.8, 0.8);
307 set_background =
true;
311 color.set_rgb_p(1.0, 0.0, 0.0);
312 set_background =
true;
317 localtime_r(&(t.tv_sec), &time_tm);
318 if (asprintf(&time,
"%02d:%02d:%02d.%06ld", time_tm.tm_hour,
319 time_tm.tm_min, time_tm.tm_sec, t.tv_usec) == -1) {
320 timestr =
"OutOfMemory";
325 Gtk::TreeModel::Row row = *__list->append();
326 row[__record.loglevel] = loglevel;
327 row[__record.time] = timestr;
328 row[__record.component] = component;
329 if ( is_exception ) {
330 row[__record.message] = std::string(
"[EXCEPTION] ") + message;
332 row[__record.message] = message;
334 if ( set_foreground ) row[__record.foreground] = color;
335 if ( set_background ) row[__record.background] = color;
337 if (time) free(time);
346 if ( (msg->
cid() == FAWKES_CID_NETWORKLOGGER) &&
364 LogView::LogRecord::LogRecord()
sigc::signal< void > signal_disconnected()
Get "disconnected" signal.
sigc::signal< void > signal_connected()
Get "connected" signal.
Message sent over the network with a log message.
informational output about normal procedures
Simple Fawkes network client.
void clear()
Clear all records.
FawkesNetworkClient * get_client()
Get the used FawkesNetworkClient.
Fawkes library namespace.
void enqueue(FawkesNetworkMessage *message)
Enqueue message to send.
Representation of a message that is sent over the network.
warning, should be investigated but software still functions, an example is that something was reques...
unsigned short int msgid() const
Get message type ID.
void set_client(FawkesNetworkClient *client)
Set Fawkes network client.
void append_message(Logger::LogLevel log_level, struct timeval t, const char *component, bool is_exception, const char *message)
Append a single message.
Logger::LogLevel get_loglevel() const
Log level.
const char * get_component() const
Get component.
error, may be recoverable (software still running) or not (software has to terminate).
bool connected() const
Check if connection is alive.
struct timeval get_time() const
Get time.
debug output, relevant only when tracking down problems
MT * msgc() const
Get correctly parsed output.
ConnectionDispatcher * get_connection_dispatcher() const
Get ConnectionDispatcher instance that is used internally.
const char * get_message() const
Get message.
Unsubscribe from receiving logging messages.
sigc::signal< void, FawkesNetworkMessage * > signal_message_received()
Get "message received" signal.
unsigned short int cid() const
Get component ID.
void set_client(FawkesNetworkClient *client)
Set FawkesNetworkClient instance.
FawkesNetworkClient * get_client()
Get client.
Watches network client events and dispatches them as signals.
Subscribe for logging messages.
bool is_exception() const
Check if message was generated by exception.