CWS-TOOLING: integrate CWS os146
[LibreOffice.git] / comphelper / source / misc / uieventslogger.cxx
blob738a5ec6a8d3d741e0e352f1a8b61a7884728ff1
1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * Copyright 2000, 2010 Oracle and/or its affiliates.
6 * OpenOffice.org - a multi-platform office productivity suite
8 * This file is part of OpenOffice.org.
10 * OpenOffice.org is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License version 3
12 * only, as published by the Free Software Foundation.
14 * OpenOffice.org is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License version 3 for more details
18 * (a copy is included in the LICENSE file that accompanied this code).
20 * You should have received a copy of the GNU Lesser General Public License
21 * version 3 along with OpenOffice.org. If not, see
22 * <http://www.openoffice.org/license.html>
23 * for a copy of the LGPLv3 License.
25 ***********************************************************************/
27 // MARKER(update_precomp.py): autogen include statement, do not remove
28 #include "precompiled_comphelper.hxx"
30 #include <comphelper/uieventslogger.hxx>
31 #include <boost/shared_ptr.hpp>
32 #include <com/sun/star/frame/XDesktop.hpp>
33 #include <com/sun/star/frame/XTerminateListener.hpp>
34 #include <com/sun/star/lang/XEventListener.hpp>
35 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/logging/LogLevel.hpp>
38 #include <com/sun/star/logging/XCsvLogFormatter.hpp>
39 #include <com/sun/star/logging/XLogHandler.hpp>
40 #include <com/sun/star/logging/XLogger.hpp>
41 #include <com/sun/star/logging/XLoggerPool.hpp>
42 #include <com/sun/star/oooimprovement/XCoreController.hpp>
43 #include <com/sun/star/uno/Sequence.hxx>
44 #include <com/sun/star/util/XStringSubstitution.hpp>
45 #include <comphelper/configurationhelper.hxx>
46 #include <comphelper/processfactory.hxx>
47 #include <map>
48 #include <osl/file.hxx>
49 #include <osl/mutex.hxx>
50 #include <osl/time.h>
51 #include <rtl/ustrbuf.hxx>
54 using namespace com::sun::star::beans;
55 using namespace com::sun::star::frame;
56 using namespace com::sun::star::lang;
57 using namespace com::sun::star::logging;
58 using namespace com::sun::star::oooimprovement;
59 using namespace com::sun::star::uno;
60 using namespace com::sun::star::util;
61 using namespace cppu;
62 using namespace osl;
63 using namespace rtl;
64 using namespace std;
67 namespace
69 static void lcl_SetupOriginAppAbbr(map<OUString, OUString>& abbrs)
71 abbrs[OUString::createFromAscii("com.sun.star.text.TextDocument")] = OUString::createFromAscii("W"); // Writer
72 abbrs[OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument")] = OUString::createFromAscii("C"); // Calc
73 abbrs[OUString::createFromAscii("com.sun.star.presentation.PresentationDocument")] = OUString::createFromAscii("I"); // Impress
74 abbrs[OUString::createFromAscii("com.sun.star.drawing.DrawingDocument")] = OUString::createFromAscii("D"); // Draw
77 static void lcl_SetupOriginWidgetAbbr(map<OUString,OUString>& abbrs)
79 abbrs[OUString::createFromAscii("ButtonToolbarController")] = OUString::createFromAscii("0");
80 abbrs[OUString::createFromAscii("ComplexToolbarController")] = OUString::createFromAscii("1");
81 abbrs[OUString::createFromAscii("ControlMenuController")] = OUString::createFromAscii("2");
82 abbrs[OUString::createFromAscii("FontMenuController")] = OUString::createFromAscii("3");
83 abbrs[OUString::createFromAscii("FontSizeMenuController")] = OUString::createFromAscii("4");
84 abbrs[OUString::createFromAscii("FooterMenuController")] = OUString::createFromAscii("5");
85 abbrs[OUString::createFromAscii("GenericToolbarController")] = OUString::createFromAscii("6");
86 abbrs[OUString::createFromAscii("HeaderMenuController")] = OUString::createFromAscii("7");
87 abbrs[OUString::createFromAscii("LanguageSelectionMenuController")] = OUString::createFromAscii("8");
88 abbrs[OUString::createFromAscii("LangSelectionStatusbarController")] = OUString::createFromAscii("9");
89 abbrs[OUString::createFromAscii("MacrosMenuController")] = OUString::createFromAscii("10");
90 abbrs[OUString::createFromAscii("MenuBarManager")] = OUString::createFromAscii("11");
91 abbrs[OUString::createFromAscii("NewMenuController")] = OUString::createFromAscii("12");
92 abbrs[OUString::createFromAscii("ObjectMenuController")] = OUString::createFromAscii("13");
93 abbrs[OUString::createFromAscii("RecentFilesMenuController")] = OUString::createFromAscii("14");
94 abbrs[OUString::createFromAscii("ToolbarsMenuController")] = OUString::createFromAscii("15");
95 abbrs[OUString::createFromAscii("SfxToolBoxControl")] = OUString::createFromAscii("16");
96 abbrs[OUString::createFromAscii("SfxAsyncExec")] = OUString::createFromAscii("17");
97 abbrs[OUString::createFromAscii("AcceleratorExecute")] = OUString::createFromAscii("18");
101 namespace comphelper
103 // declaration of implementation
104 class UiEventsLogger_Impl;
105 class UiEventsLogger_Impl : public UiEventsLogger
107 private:
108 //typedefs and friends
109 friend class UiEventsLogger;
110 typedef UiEventsLogger_Impl* ptr;
112 // instance methods and data
113 UiEventsLogger_Impl();
114 void initializeLogger();
115 void logDispatch(const ::com::sun::star::util::URL& url,
116 const Sequence<PropertyValue>& args);
117 void logRotated();
118 void logVcl(const ::rtl::OUString& parent_id,
119 sal_Int32 window_type,
120 const ::rtl::OUString& id,
121 const ::rtl::OUString& method,
122 const ::rtl::OUString& param);
123 void rotate();
124 void hotRotate();
125 void prepareLogHandler();
126 void checkIdleTimeout();
127 OUString getCurrentPath();
128 OUString getRotatedPath();
129 void disposing();
131 bool m_Active;
132 TimeValue m_LastLogEventTime;
133 const OUString m_LogPath;
134 const TimeValue m_IdleTimeout;
135 sal_Int32 m_SessionLogEventCount;
136 Reference<XLogger> m_Logger;
137 Reference<XLogHandler> m_LogHandler;
138 Reference<XCsvLogFormatter> m_Formatter;
139 map<OUString, OUString> m_OriginAppAbbr;
140 map<OUString, OUString> m_OriginWidgetAbbr;
143 // static methods and data
144 static ptr getInstance();
145 static void prepareMutex();
146 static bool shouldActivate();
147 static bool getEnabledFromCoreController();
148 static bool getEnabledFromCfg();
149 static TimeValue getIdleTimeoutFromCfg();
150 static OUString getLogPathFromCfg();
151 static sal_Int32 findIdx(const Sequence<PropertyValue>& args, const OUString& key);
153 static ptr instance;
154 static Mutex * singleton_mutex;
155 static const sal_Int32 COLUMNS;
156 static const OUString CFG_ENABLED;
157 static const OUString CFG_IDLETIMEOUT;
158 static const OUString CFG_LOGGING;
159 static const OUString CFG_LOGPATH;
160 static const OUString CFG_OOOIMPROVEMENT;
161 static const OUString ETYPE_DISPATCH;
162 static const OUString ETYPE_ROTATED;
163 static const OUString ETYPE_VCL;
164 static const OUString CSSL_CSVFORMATTER;
165 static const OUString CSSL_FILEHANDLER;
166 static const OUString CSSL_LOGGERPOOL;
167 static const OUString CSSO_CORECONTROLLER;
168 static const OUString CSST_JOBEXECUTOR;
169 static const OUString CSSU_PATHSUB;
170 static const OUString LOGGERNAME;
171 static const OUString LOGORIGINAPP;
172 static const OUString LOGORIGINWIDGET;
173 static const OUString UNKNOWN_ORIGIN;
174 static const OUString FN_CURRENTLOG;
175 static const OUString FN_ROTATEDLOG;
176 static const OUString LOGROTATE_EVENTNAME;
177 static const OUString URL_UNO;
178 static const OUString URL_SPECIAL;
179 static const OUString URL_FILE;
183 namespace comphelper
185 // consts
186 const sal_Int32 UiEventsLogger_Impl::COLUMNS = 9;
187 const OUString UiEventsLogger_Impl::CFG_ENABLED = OUString::createFromAscii("EnablingAllowed");
188 const OUString UiEventsLogger_Impl::CFG_IDLETIMEOUT = OUString::createFromAscii("IdleTimeout");
189 const OUString UiEventsLogger_Impl::CFG_LOGGING = OUString::createFromAscii("/org.openoffice.Office.Logging");
190 const OUString UiEventsLogger_Impl::CFG_LOGPATH = OUString::createFromAscii("LogPath");
191 const OUString UiEventsLogger_Impl::CFG_OOOIMPROVEMENT = OUString::createFromAscii("OOoImprovement");
193 const OUString UiEventsLogger_Impl::CSSL_CSVFORMATTER = OUString::createFromAscii("com.sun.star.logging.CsvFormatter");
194 const OUString UiEventsLogger_Impl::CSSL_FILEHANDLER = OUString::createFromAscii("com.sun.star.logging.FileHandler");
195 const OUString UiEventsLogger_Impl::CSSL_LOGGERPOOL = OUString::createFromAscii("com.sun.star.logging.LoggerPool");
196 const OUString UiEventsLogger_Impl::CSSO_CORECONTROLLER = OUString::createFromAscii("com.sun.star.oooimprovement.CoreController");
197 const OUString UiEventsLogger_Impl::CSSU_PATHSUB = OUString::createFromAscii("com.sun.star.util.PathSubstitution");
199 const OUString UiEventsLogger_Impl::ETYPE_DISPATCH = OUString::createFromAscii("dispatch");
200 const OUString UiEventsLogger_Impl::ETYPE_ROTATED = OUString::createFromAscii("rotated");
201 const OUString UiEventsLogger_Impl::ETYPE_VCL = OUString::createFromAscii("vcl");
203 const OUString UiEventsLogger_Impl::LOGGERNAME = OUString::createFromAscii("org.openoffice.oooimprovement.Core.UiEventsLogger");
204 const OUString UiEventsLogger_Impl::LOGORIGINWIDGET = OUString::createFromAscii("comphelper.UiEventsLogger.LogOriginWidget");
205 const OUString UiEventsLogger_Impl::LOGORIGINAPP = OUString::createFromAscii("comphelper.UiEventsLogger.LogOriginApp");
207 const OUString UiEventsLogger_Impl::UNKNOWN_ORIGIN = OUString::createFromAscii("unknown origin");
208 const OUString UiEventsLogger_Impl::FN_CURRENTLOG = OUString::createFromAscii("Current");
209 const OUString UiEventsLogger_Impl::FN_ROTATEDLOG = OUString::createFromAscii("OOoImprove");
210 const OUString UiEventsLogger_Impl::LOGROTATE_EVENTNAME = OUString::createFromAscii("onOOoImprovementLogRotated");
212 const OUString UiEventsLogger_Impl::URL_UNO = OUString::createFromAscii(".uno:");
213 const OUString UiEventsLogger_Impl::URL_SPECIAL = OUString::createFromAscii(".special:");
214 const OUString UiEventsLogger_Impl::URL_FILE = OUString::createFromAscii("file:");
217 // public UiEventsLogger interface
218 sal_Bool UiEventsLogger::isEnabled()
220 if ( UiEventsLogger_Impl::getEnabledFromCfg() )
222 try {
223 UiEventsLogger_Impl::prepareMutex();
224 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
225 return UiEventsLogger_Impl::getInstance()->m_Active;
226 } catch(...) { return false; } // never throws
227 } // if ( )
228 return sal_False;
231 sal_Int32 UiEventsLogger::getSessionLogEventCount()
233 try {
234 UiEventsLogger_Impl::prepareMutex();
235 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
236 return UiEventsLogger_Impl::getInstance()->m_SessionLogEventCount;
237 } catch(...) { return 0; } // never throws
240 void UiEventsLogger::appendDispatchOrigin(
241 Sequence<PropertyValue>& args,
242 const OUString& originapp,
243 const OUString& originwidget)
245 sal_Int32 old_length = args.getLength();
246 args.realloc(old_length+2);
247 args[old_length].Name = UiEventsLogger_Impl::LOGORIGINAPP;
248 args[old_length].Value = static_cast<Any>(originapp);
249 args[old_length+1].Name = UiEventsLogger_Impl::LOGORIGINWIDGET;
250 args[old_length+1].Value = static_cast<Any>(originwidget);
253 Sequence<PropertyValue> UiEventsLogger::purgeDispatchOrigin(
254 const Sequence<PropertyValue>& args)
256 Sequence<PropertyValue> result(args.getLength());
257 sal_Int32 target_idx=0;
258 for(sal_Int32 source_idx=0; source_idx<args.getLength(); source_idx++)
259 if(args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINAPP
260 && args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINWIDGET)
261 result[target_idx++] = args[source_idx];
262 result.realloc(target_idx);
263 return result;
266 void UiEventsLogger::logDispatch(
267 const URL& url,
268 const Sequence<PropertyValue>& args)
270 try {
271 UiEventsLogger_Impl::prepareMutex();
272 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
273 UiEventsLogger_Impl::getInstance()->logDispatch(url, args);
274 } catch(...) { } // never throws
277 void UiEventsLogger::logVcl(
278 const OUString& parent_id,
279 sal_Int32 window_type,
280 const OUString& id,
281 const OUString& method,
282 const OUString& param)
284 try {
285 UiEventsLogger_Impl::prepareMutex();
286 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
287 UiEventsLogger_Impl::getInstance()->logVcl(parent_id, window_type, id, method, param);
288 } catch(...) { } // never throws
291 void UiEventsLogger::logVcl(
292 const OUString& parent_id,
293 sal_Int32 window_type,
294 const OUString& id,
295 const OUString& method,
296 sal_Int32 param)
298 OUStringBuffer buf;
299 UiEventsLogger::logVcl(parent_id, window_type, id, method, buf.append(param).makeStringAndClear());
302 void UiEventsLogger::logVcl(
303 const OUString& parent_id,
304 sal_Int32 window_type,
305 const OUString& id,
306 const OUString& method)
308 OUString empty;
309 UiEventsLogger::logVcl(parent_id, window_type, id, method, empty);
312 void UiEventsLogger::disposing()
314 // we dont want to create an instance just to dispose it
315 UiEventsLogger_Impl::prepareMutex();
316 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
317 if(UiEventsLogger_Impl::instance!=UiEventsLogger_Impl::ptr())
318 UiEventsLogger_Impl::getInstance()->disposing();
321 void UiEventsLogger::reinit()
323 UiEventsLogger_Impl::prepareMutex();
324 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
325 if(UiEventsLogger_Impl::instance)
327 UiEventsLogger_Impl::instance->disposing();
328 delete UiEventsLogger_Impl::instance;
329 UiEventsLogger_Impl::instance = NULL;
333 // private UiEventsLogger_Impl methods
334 UiEventsLogger_Impl::UiEventsLogger_Impl()
335 : m_Active(UiEventsLogger_Impl::shouldActivate())
336 , m_LogPath(UiEventsLogger_Impl::getLogPathFromCfg())
337 , m_IdleTimeout(UiEventsLogger_Impl::getIdleTimeoutFromCfg())
338 , m_SessionLogEventCount(0)
340 lcl_SetupOriginAppAbbr(m_OriginAppAbbr);
341 lcl_SetupOriginWidgetAbbr(m_OriginWidgetAbbr);
342 m_LastLogEventTime.Seconds = m_LastLogEventTime.Nanosec = 0;
343 if(m_Active) rotate();
344 if(m_Active) initializeLogger();
347 void UiEventsLogger_Impl::logDispatch(
348 const URL& url,
349 const Sequence<PropertyValue>& args)
351 if(!m_Active) return;
352 if(!url.Complete.match(URL_UNO)
353 && !url.Complete.match(URL_FILE)
354 && !url.Complete.match(URL_SPECIAL))
356 return;
358 checkIdleTimeout();
360 Sequence<OUString> logdata = Sequence<OUString>(COLUMNS);
361 logdata[0] = ETYPE_DISPATCH;
362 sal_Int32 originapp_idx = findIdx(args, LOGORIGINAPP);
363 if(originapp_idx!=-1)
365 OUString app;
366 args[originapp_idx].Value >>= app;
367 map<OUString, OUString>::iterator abbr_it = m_OriginAppAbbr.find(app);
368 if(abbr_it != m_OriginAppAbbr.end())
369 app = abbr_it->second;
370 logdata[1] = app;
372 else
373 logdata[1] = UNKNOWN_ORIGIN;
374 sal_Int32 originwidget_idx = findIdx(args, LOGORIGINWIDGET);
375 if(originwidget_idx!=-1)
377 OUString widget;
378 args[originwidget_idx].Value >>= widget;
379 map<OUString, OUString>::iterator widget_it = m_OriginWidgetAbbr.find(widget);
380 if(widget_it != m_OriginWidgetAbbr.end())
381 widget = widget_it->second;
382 logdata[2] = widget;
384 else
385 logdata[2] = UNKNOWN_ORIGIN;
386 if(url.Complete.match(URL_FILE))
387 logdata[3] = URL_FILE;
388 else
389 logdata[3] = url.Main;
390 OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s",
391 OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(),
392 OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(),
393 OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(),
394 OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(),
395 OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(),
396 OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(),
397 OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(),
398 OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(),
399 OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr());
400 m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata));
401 m_SessionLogEventCount++;
404 void UiEventsLogger_Impl::logRotated()
406 Sequence<OUString> logdata = Sequence<OUString>(COLUMNS);
407 logdata[0] = ETYPE_ROTATED;
408 OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s",
409 OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(),
410 OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(),
411 OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(),
412 OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(),
413 OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(),
414 OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(),
415 OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(),
416 OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(),
417 OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr());
418 m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata));
421 void UiEventsLogger_Impl::logVcl(
422 const OUString& parent_id,
423 sal_Int32 window_type,
424 const OUString& id,
425 const OUString& method,
426 const OUString& param)
428 if(!m_Active) return;
429 checkIdleTimeout();
431 OUStringBuffer buf;
432 Sequence<OUString> logdata = Sequence<OUString>(COLUMNS);
433 logdata[0] = ETYPE_VCL;
434 logdata[4] = parent_id;
435 logdata[5] = buf.append(window_type).makeStringAndClear();
436 logdata[6] = id;
437 logdata[7] = method;
438 logdata[8] = param;
439 OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s",
440 OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(),
441 OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(),
442 OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(),
443 OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(),
444 OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(),
445 OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(),
446 OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(),
447 OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(),
448 OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr());
449 m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata));
450 m_SessionLogEventCount++;
453 void UiEventsLogger_Impl::rotate()
455 FileBase::RC result = File::move(getCurrentPath(), getRotatedPath());
456 if(result!=FileBase::E_None && result!=FileBase::E_NOENT)
457 m_Active = false;
460 void UiEventsLogger_Impl::hotRotate()
462 logRotated();
463 m_Logger->removeLogHandler(m_LogHandler);
464 m_LogHandler = NULL;
465 rotate();
466 prepareLogHandler();
467 if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is())
469 m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY));
470 m_LogHandler->setLevel(LogLevel::ALL);
471 m_Logger->addLogHandler(m_LogHandler);
473 else
474 m_Active = false;
477 void UiEventsLogger_Impl::prepareLogHandler()
479 Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
481 Sequence<Any> init_args = Sequence<Any>(1);
482 init_args[0] = static_cast<Any>(getCurrentPath());
483 Reference< XInterface > temp =
484 sm->createInstanceWithArguments(CSSL_FILEHANDLER, init_args);
485 m_LogHandler = Reference<XLogHandler>(temp, UNO_QUERY);
488 void UiEventsLogger_Impl::checkIdleTimeout()
490 TimeValue now;
491 osl_getSystemTime(&now);
492 if(now.Seconds - m_LastLogEventTime.Seconds > m_IdleTimeout.Seconds && m_SessionLogEventCount>0)
493 hotRotate();
494 m_LastLogEventTime = now;
497 OUString UiEventsLogger_Impl::getCurrentPath()
499 OUStringBuffer current_path(m_LogPath);
500 current_path.appendAscii("/");
501 current_path.append(FN_CURRENTLOG);
502 current_path.appendAscii(".csv");
503 return current_path.makeStringAndClear();
506 OUString UiEventsLogger_Impl::getRotatedPath()
508 OUStringBuffer rotated_path(m_LogPath);
509 rotated_path.appendAscii("/");
510 rotated_path.append(FN_ROTATEDLOG);
511 rotated_path.appendAscii("-");
513 // ISO 8601
514 char tsrotated_pathfer[20];
515 oslDateTime now;
516 TimeValue now_tv;
517 osl_getSystemTime(&now_tv);
518 osl_getDateTimeFromTimeValue(&now_tv, &now);
519 const size_t rotated_pathfer_size = sizeof(tsrotated_pathfer);
520 snprintf(tsrotated_pathfer, rotated_pathfer_size, "%04i-%02i-%02iT%02i_%02i_%02i",
521 now.Year,
522 now.Month,
523 now.Day,
524 now.Hours,
525 now.Minutes,
526 now.Seconds);
527 rotated_path.appendAscii(tsrotated_pathfer);
528 rotated_path.appendAscii(".csv");
530 return rotated_path.makeStringAndClear();
533 void UiEventsLogger_Impl::initializeLogger()
535 Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
537 // getting the Core Uno proxy object
538 // It will call disposing and make sure we clear all our references
540 Reference<XTerminateListener> xCore(
541 sm->createInstance(OUString::createFromAscii("com.sun.star.oooimprovement.Core")),
542 UNO_QUERY);
543 Reference<XDesktop> xDesktop(
544 sm->createInstance(OUString::createFromAscii("com.sun.star.frame.Desktop")),
545 UNO_QUERY);
546 if(!(xCore.is() && xDesktop.is()))
548 m_Active = false;
549 return;
551 xDesktop->addTerminateListener(xCore);
553 // getting the LoggerPool
554 Reference<XLoggerPool> pool;
556 Reference<XInterface> temp =
557 sm->createInstance(CSSL_LOGGERPOOL);
558 pool = Reference<XLoggerPool>(temp, UNO_QUERY);
561 // getting the Logger
562 m_Logger = pool->getNamedLogger(LOGGERNAME);
564 // getting the FileHandler
565 prepareLogHandler();
567 // getting the Formatter
569 Reference<XInterface> temp =
570 sm->createInstance(CSSL_CSVFORMATTER);
571 m_Formatter = Reference<XCsvLogFormatter>(temp, UNO_QUERY);
574 if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is())
576 Sequence<OUString> columns = Sequence<OUString>(COLUMNS);
577 columns[0] = OUString::createFromAscii("eventtype");
578 columns[1] = OUString::createFromAscii("originapp");
579 columns[2] = OUString::createFromAscii("originwidget");
580 columns[3] = OUString::createFromAscii("uno url");
581 columns[4] = OUString::createFromAscii("parent id");
582 columns[5] = OUString::createFromAscii("window type");
583 columns[6] = OUString::createFromAscii("id");
584 columns[7] = OUString::createFromAscii("method");
585 columns[8] = OUString::createFromAscii("parameter");
586 m_Formatter->setColumnnames(columns);
587 m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY));
588 m_Logger->setLevel(LogLevel::ALL);
589 m_LogHandler->setLevel(LogLevel::ALL);
590 m_Logger->addLogHandler(m_LogHandler);
592 else
593 m_Active = false;
596 // private static UiEventsLogger_Impl
597 bool UiEventsLogger_Impl::shouldActivate()
599 return getEnabledFromCfg() && getEnabledFromCoreController();
602 OUString UiEventsLogger_Impl::getLogPathFromCfg()
604 OUString result;
605 Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
607 ConfigurationHelper::readDirectKey(
609 CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_LOGPATH,
610 ConfigurationHelper::E_READONLY
611 ) >>= result;
613 Reference<XStringSubstitution> path_sub(
614 sm->createInstance(CSSU_PATHSUB),
615 UNO_QUERY);
616 if(path_sub.is())
617 result = path_sub->substituteVariables(result, sal_False);
618 return result;
621 TimeValue UiEventsLogger_Impl::getIdleTimeoutFromCfg()
623 sal_Int32 timeoutminutes = 360;
624 Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
626 ConfigurationHelper::readDirectKey(
628 CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_IDLETIMEOUT,
629 ConfigurationHelper::E_READONLY
630 ) >>= timeoutminutes;
631 TimeValue result;
632 result.Seconds = static_cast<sal_uInt32>(timeoutminutes)*60;
633 result.Nanosec = 0;
634 return result;
637 bool UiEventsLogger_Impl::getEnabledFromCfg()
639 sal_Bool result = false;
640 Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
641 ConfigurationHelper::readDirectKey(
643 CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_ENABLED,
644 ::comphelper::ConfigurationHelper::E_READONLY
645 ) >>= result;
646 return result;
649 bool UiEventsLogger_Impl::getEnabledFromCoreController()
651 Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
652 Reference<XCoreController> core_c(
653 sm->createInstance(OUString::createFromAscii("com.sun.star.oooimprovement.CoreController")),
654 UNO_QUERY);
655 if(!core_c.is()) return false;
656 return core_c->enablingUiEventsLoggerAllowed(1);
659 UiEventsLogger_Impl::ptr UiEventsLogger_Impl::instance = UiEventsLogger_Impl::ptr();
660 UiEventsLogger_Impl::ptr UiEventsLogger_Impl::getInstance()
662 if(instance == NULL)
663 instance = UiEventsLogger_Impl::ptr(new UiEventsLogger_Impl());
664 return instance;
667 Mutex * UiEventsLogger_Impl::singleton_mutex = NULL;
668 void UiEventsLogger_Impl::prepareMutex()
670 if(singleton_mutex == NULL)
672 Guard<Mutex> global_guard(Mutex::getGlobalMutex());
673 if(singleton_mutex == NULL)
674 singleton_mutex = new Mutex();
678 sal_Int32 UiEventsLogger_Impl::findIdx(const Sequence<PropertyValue>& args, const OUString& key)
680 for(sal_Int32 i=0; i<args.getLength(); i++)
681 if(args[i].Name == key)
682 return i;
683 return -1;
686 void UiEventsLogger_Impl::disposing()
688 m_Active = false;
689 m_Logger.clear() ;
690 m_LogHandler.clear();
691 m_Formatter.clear();