1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_comphelper.hxx" 26 27 #include <comphelper/uieventslogger.hxx> 28 #include <boost/shared_ptr.hpp> 29 #include <com/sun/star/frame/XDesktop.hpp> 30 #include <com/sun/star/frame/XTerminateListener.hpp> 31 #include <com/sun/star/lang/XEventListener.hpp> 32 #include <com/sun/star/lang/XMultiComponentFactory.hpp> 33 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 34 #include <com/sun/star/logging/LogLevel.hpp> 35 #include <com/sun/star/logging/XCsvLogFormatter.hpp> 36 #include <com/sun/star/logging/XLogHandler.hpp> 37 #include <com/sun/star/logging/XLogger.hpp> 38 #include <com/sun/star/logging/XLoggerPool.hpp> 39 #include <com/sun/star/oooimprovement/XCoreController.hpp> 40 #include <com/sun/star/uno/Sequence.hxx> 41 #include <com/sun/star/util/XStringSubstitution.hpp> 42 #include <comphelper/configurationhelper.hxx> 43 #include <comphelper/processfactory.hxx> 44 #include <map> 45 #include <osl/file.hxx> 46 #include <osl/mutex.hxx> 47 #include <osl/time.h> 48 #include <rtl/ustrbuf.hxx> 49 50 51 using namespace com::sun::star::beans; 52 using namespace com::sun::star::frame; 53 using namespace com::sun::star::lang; 54 using namespace com::sun::star::logging; 55 using namespace com::sun::star::oooimprovement; 56 using namespace com::sun::star::uno; 57 using namespace com::sun::star::util; 58 using namespace cppu; 59 using namespace osl; 60 using namespace rtl; 61 using namespace std; 62 63 64 namespace 65 { lcl_SetupOriginAppAbbr(map<OUString,OUString> & abbrs)66 static void lcl_SetupOriginAppAbbr(map<OUString, OUString>& abbrs) 67 { 68 abbrs[OUString::createFromAscii("com.sun.star.text.TextDocument")] = OUString::createFromAscii("W"); // Writer 69 abbrs[OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument")] = OUString::createFromAscii("C"); // Calc 70 abbrs[OUString::createFromAscii("com.sun.star.presentation.PresentationDocument")] = OUString::createFromAscii("I"); // Impress 71 abbrs[OUString::createFromAscii("com.sun.star.drawing.DrawingDocument")] = OUString::createFromAscii("D"); // Draw 72 }; 73 lcl_SetupOriginWidgetAbbr(map<OUString,OUString> & abbrs)74 static void lcl_SetupOriginWidgetAbbr(map<OUString,OUString>& abbrs) 75 { 76 abbrs[OUString::createFromAscii("ButtonToolbarController")] = OUString::createFromAscii("0"); 77 abbrs[OUString::createFromAscii("ComplexToolbarController")] = OUString::createFromAscii("1"); 78 abbrs[OUString::createFromAscii("ControlMenuController")] = OUString::createFromAscii("2"); 79 abbrs[OUString::createFromAscii("FontMenuController")] = OUString::createFromAscii("3"); 80 abbrs[OUString::createFromAscii("FontSizeMenuController")] = OUString::createFromAscii("4"); 81 abbrs[OUString::createFromAscii("FooterMenuController")] = OUString::createFromAscii("5"); 82 abbrs[OUString::createFromAscii("GenericToolbarController")] = OUString::createFromAscii("6"); 83 abbrs[OUString::createFromAscii("HeaderMenuController")] = OUString::createFromAscii("7"); 84 abbrs[OUString::createFromAscii("LanguageSelectionMenuController")] = OUString::createFromAscii("8"); 85 abbrs[OUString::createFromAscii("LangSelectionStatusbarController")] = OUString::createFromAscii("9"); 86 abbrs[OUString::createFromAscii("MacrosMenuController")] = OUString::createFromAscii("10"); 87 abbrs[OUString::createFromAscii("MenuBarManager")] = OUString::createFromAscii("11"); 88 abbrs[OUString::createFromAscii("NewMenuController")] = OUString::createFromAscii("12"); 89 abbrs[OUString::createFromAscii("ObjectMenuController")] = OUString::createFromAscii("13"); 90 abbrs[OUString::createFromAscii("RecentFilesMenuController")] = OUString::createFromAscii("14"); 91 abbrs[OUString::createFromAscii("ToolbarsMenuController")] = OUString::createFromAscii("15"); 92 abbrs[OUString::createFromAscii("SfxToolBoxControl")] = OUString::createFromAscii("16"); 93 abbrs[OUString::createFromAscii("SfxAsyncExec")] = OUString::createFromAscii("17"); 94 abbrs[OUString::createFromAscii("AcceleratorExecute")] = OUString::createFromAscii("18"); 95 }; 96 } 97 98 namespace comphelper 99 { 100 // declaration of implementation 101 class UiEventsLogger_Impl; 102 class UiEventsLogger_Impl : public UiEventsLogger 103 { 104 private: 105 //typedefs and friends 106 friend class UiEventsLogger; 107 typedef UiEventsLogger_Impl* ptr; 108 109 // instance methods and data 110 UiEventsLogger_Impl(); 111 void initializeLogger(); 112 void logDispatch(const ::com::sun::star::util::URL& url, 113 const Sequence<PropertyValue>& args); 114 void logRotated(); 115 void logVcl(const ::rtl::OUString& parent_id, 116 sal_Int32 window_type, 117 const ::rtl::OUString& id, 118 const ::rtl::OUString& method, 119 const ::rtl::OUString& param); 120 void rotate(); 121 void hotRotate(); 122 void prepareLogHandler(); 123 void checkIdleTimeout(); 124 OUString getCurrentPath(); 125 OUString getRotatedPath(); 126 void disposing(); 127 128 bool m_Active; 129 TimeValue m_LastLogEventTime; 130 const OUString m_LogPath; 131 const TimeValue m_IdleTimeout; 132 sal_Int32 m_SessionLogEventCount; 133 Reference<XLogger> m_Logger; 134 Reference<XLogHandler> m_LogHandler; 135 Reference<XCsvLogFormatter> m_Formatter; 136 map<OUString, OUString> m_OriginAppAbbr; 137 map<OUString, OUString> m_OriginWidgetAbbr; 138 139 140 // static methods and data 141 static ptr getInstance(); 142 static void prepareMutex(); 143 static bool shouldActivate(); 144 static bool getEnabledFromCoreController(); 145 static bool getEnabledFromCfg(); 146 static TimeValue getIdleTimeoutFromCfg(); 147 static OUString getLogPathFromCfg(); 148 static sal_Int32 findIdx(const Sequence<PropertyValue>& args, const OUString& key); 149 150 static ptr instance; 151 static Mutex * singleton_mutex; 152 static const sal_Int32 COLUMNS; 153 static const OUString CFG_ENABLED; 154 static const OUString CFG_IDLETIMEOUT; 155 static const OUString CFG_LOGGING; 156 static const OUString CFG_LOGPATH; 157 static const OUString CFG_OOOIMPROVEMENT; 158 static const OUString ETYPE_DISPATCH; 159 static const OUString ETYPE_ROTATED; 160 static const OUString ETYPE_VCL; 161 static const OUString CSSL_CSVFORMATTER; 162 static const OUString CSSL_FILEHANDLER; 163 static const OUString CSSL_LOGGERPOOL; 164 static const OUString CSSO_CORECONTROLLER; 165 static const OUString CSST_JOBEXECUTOR; 166 static const OUString CSSU_PATHSUB; 167 static const OUString LOGGERNAME; 168 static const OUString LOGORIGINAPP; 169 static const OUString LOGORIGINWIDGET; 170 static const OUString UNKNOWN_ORIGIN; 171 static const OUString FN_CURRENTLOG; 172 static const OUString FN_ROTATEDLOG; 173 static const OUString LOGROTATE_EVENTNAME; 174 static const OUString URL_UNO; 175 static const OUString URL_SPECIAL; 176 static const OUString URL_FILE; 177 }; 178 } 179 180 namespace comphelper 181 { 182 // consts 183 const sal_Int32 UiEventsLogger_Impl::COLUMNS = 9; 184 const OUString UiEventsLogger_Impl::CFG_ENABLED = OUString::createFromAscii("EnablingAllowed"); 185 const OUString UiEventsLogger_Impl::CFG_IDLETIMEOUT = OUString::createFromAscii("IdleTimeout"); 186 const OUString UiEventsLogger_Impl::CFG_LOGGING = OUString::createFromAscii("/org.openoffice.Office.Logging"); 187 const OUString UiEventsLogger_Impl::CFG_LOGPATH = OUString::createFromAscii("LogPath"); 188 const OUString UiEventsLogger_Impl::CFG_OOOIMPROVEMENT = OUString::createFromAscii("OOoImprovement"); 189 190 const OUString UiEventsLogger_Impl::CSSL_CSVFORMATTER = OUString::createFromAscii("com.sun.star.logging.CsvFormatter"); 191 const OUString UiEventsLogger_Impl::CSSL_FILEHANDLER = OUString::createFromAscii("com.sun.star.logging.FileHandler"); 192 const OUString UiEventsLogger_Impl::CSSL_LOGGERPOOL = OUString::createFromAscii("com.sun.star.logging.LoggerPool"); 193 const OUString UiEventsLogger_Impl::CSSO_CORECONTROLLER = OUString::createFromAscii("com.sun.star.oooimprovement.CoreController"); 194 const OUString UiEventsLogger_Impl::CSSU_PATHSUB = OUString::createFromAscii("com.sun.star.util.PathSubstitution"); 195 196 const OUString UiEventsLogger_Impl::ETYPE_DISPATCH = OUString::createFromAscii("dispatch"); 197 const OUString UiEventsLogger_Impl::ETYPE_ROTATED = OUString::createFromAscii("rotated"); 198 const OUString UiEventsLogger_Impl::ETYPE_VCL = OUString::createFromAscii("vcl"); 199 200 const OUString UiEventsLogger_Impl::LOGGERNAME = OUString::createFromAscii("org.openoffice.oooimprovement.Core.UiEventsLogger"); 201 const OUString UiEventsLogger_Impl::LOGORIGINWIDGET = OUString::createFromAscii("comphelper.UiEventsLogger.LogOriginWidget"); 202 const OUString UiEventsLogger_Impl::LOGORIGINAPP = OUString::createFromAscii("comphelper.UiEventsLogger.LogOriginApp"); 203 204 const OUString UiEventsLogger_Impl::UNKNOWN_ORIGIN = OUString::createFromAscii("unknown origin"); 205 const OUString UiEventsLogger_Impl::FN_CURRENTLOG = OUString::createFromAscii("Current"); 206 const OUString UiEventsLogger_Impl::FN_ROTATEDLOG = OUString::createFromAscii("OOoImprove"); 207 const OUString UiEventsLogger_Impl::LOGROTATE_EVENTNAME = OUString::createFromAscii("onOOoImprovementLogRotated"); 208 209 const OUString UiEventsLogger_Impl::URL_UNO = OUString::createFromAscii(".uno:"); 210 const OUString UiEventsLogger_Impl::URL_SPECIAL = OUString::createFromAscii(".special:"); 211 const OUString UiEventsLogger_Impl::URL_FILE = OUString::createFromAscii("file:"); 212 213 214 // public UiEventsLogger interface isEnabled()215 sal_Bool UiEventsLogger::isEnabled() 216 { 217 if ( UiEventsLogger_Impl::getEnabledFromCfg() ) 218 { 219 try { 220 UiEventsLogger_Impl::prepareMutex(); 221 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); 222 return UiEventsLogger_Impl::getInstance()->m_Active; 223 } catch(...) { return false; } // never throws 224 } // if ( ) 225 return sal_False; 226 } 227 getSessionLogEventCount()228 sal_Int32 UiEventsLogger::getSessionLogEventCount() 229 { 230 try { 231 UiEventsLogger_Impl::prepareMutex(); 232 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); 233 return UiEventsLogger_Impl::getInstance()->m_SessionLogEventCount; 234 } catch(...) { return 0; } // never throws 235 } 236 appendDispatchOrigin(Sequence<PropertyValue> & args,const OUString & originapp,const OUString & originwidget)237 void UiEventsLogger::appendDispatchOrigin( 238 Sequence<PropertyValue>& args, 239 const OUString& originapp, 240 const OUString& originwidget) 241 { 242 sal_Int32 old_length = args.getLength(); 243 args.realloc(old_length+2); 244 args[old_length].Name = UiEventsLogger_Impl::LOGORIGINAPP; 245 args[old_length].Value = static_cast<Any>(originapp); 246 args[old_length+1].Name = UiEventsLogger_Impl::LOGORIGINWIDGET; 247 args[old_length+1].Value = static_cast<Any>(originwidget); 248 } 249 purgeDispatchOrigin(const Sequence<PropertyValue> & args)250 Sequence<PropertyValue> UiEventsLogger::purgeDispatchOrigin( 251 const Sequence<PropertyValue>& args) 252 { 253 Sequence<PropertyValue> result(args.getLength()); 254 sal_Int32 target_idx=0; 255 for(sal_Int32 source_idx=0; source_idx<args.getLength(); source_idx++) 256 if(args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINAPP 257 && args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINWIDGET) 258 result[target_idx++] = args[source_idx]; 259 result.realloc(target_idx); 260 return result; 261 } 262 logDispatch(const URL & url,const Sequence<PropertyValue> & args)263 void UiEventsLogger::logDispatch( 264 const URL& url, 265 const Sequence<PropertyValue>& args) 266 { 267 try { 268 UiEventsLogger_Impl::prepareMutex(); 269 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); 270 UiEventsLogger_Impl::getInstance()->logDispatch(url, args); 271 } catch(...) { } // never throws 272 } 273 logVcl(const OUString & parent_id,sal_Int32 window_type,const OUString & id,const OUString & method,const OUString & param)274 void UiEventsLogger::logVcl( 275 const OUString& parent_id, 276 sal_Int32 window_type, 277 const OUString& id, 278 const OUString& method, 279 const OUString& param) 280 { 281 try { 282 UiEventsLogger_Impl::prepareMutex(); 283 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); 284 UiEventsLogger_Impl::getInstance()->logVcl(parent_id, window_type, id, method, param); 285 } catch(...) { } // never throws 286 } 287 logVcl(const OUString & parent_id,sal_Int32 window_type,const OUString & id,const OUString & method,sal_Int32 param)288 void UiEventsLogger::logVcl( 289 const OUString& parent_id, 290 sal_Int32 window_type, 291 const OUString& id, 292 const OUString& method, 293 sal_Int32 param) 294 { 295 OUStringBuffer buf; 296 UiEventsLogger::logVcl(parent_id, window_type, id, method, buf.append(param).makeStringAndClear()); 297 } 298 logVcl(const OUString & parent_id,sal_Int32 window_type,const OUString & id,const OUString & method)299 void UiEventsLogger::logVcl( 300 const OUString& parent_id, 301 sal_Int32 window_type, 302 const OUString& id, 303 const OUString& method) 304 { 305 OUString empty; 306 UiEventsLogger::logVcl(parent_id, window_type, id, method, empty); 307 } 308 disposing()309 void UiEventsLogger::disposing() 310 { 311 // we dont want to create an instance just to dispose it 312 UiEventsLogger_Impl::prepareMutex(); 313 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); 314 if(UiEventsLogger_Impl::instance!=UiEventsLogger_Impl::ptr()) 315 UiEventsLogger_Impl::getInstance()->disposing(); 316 } 317 reinit()318 void UiEventsLogger::reinit() 319 { 320 UiEventsLogger_Impl::prepareMutex(); 321 Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); 322 if(UiEventsLogger_Impl::instance) 323 { 324 UiEventsLogger_Impl::instance->disposing(); 325 delete UiEventsLogger_Impl::instance; 326 UiEventsLogger_Impl::instance = NULL; 327 } 328 } 329 330 // private UiEventsLogger_Impl methods UiEventsLogger_Impl()331 UiEventsLogger_Impl::UiEventsLogger_Impl() 332 : m_Active(UiEventsLogger_Impl::shouldActivate()) 333 , m_LogPath(UiEventsLogger_Impl::getLogPathFromCfg()) 334 , m_IdleTimeout(UiEventsLogger_Impl::getIdleTimeoutFromCfg()) 335 , m_SessionLogEventCount(0) 336 { 337 lcl_SetupOriginAppAbbr(m_OriginAppAbbr); 338 lcl_SetupOriginWidgetAbbr(m_OriginWidgetAbbr); 339 m_LastLogEventTime.Seconds = m_LastLogEventTime.Nanosec = 0; 340 if(m_Active) rotate(); 341 if(m_Active) initializeLogger(); 342 } 343 logDispatch(const URL & url,const Sequence<PropertyValue> & args)344 void UiEventsLogger_Impl::logDispatch( 345 const URL& url, 346 const Sequence<PropertyValue>& args) 347 { 348 if(!m_Active) return; 349 if(!url.Complete.match(URL_UNO) 350 && !url.Complete.match(URL_FILE) 351 && !url.Complete.match(URL_SPECIAL)) 352 { 353 return; 354 } 355 checkIdleTimeout(); 356 357 Sequence<OUString> logdata = Sequence<OUString>(COLUMNS); 358 logdata[0] = ETYPE_DISPATCH; 359 sal_Int32 originapp_idx = findIdx(args, LOGORIGINAPP); 360 if(originapp_idx!=-1) 361 { 362 OUString app; 363 args[originapp_idx].Value >>= app; 364 map<OUString, OUString>::iterator abbr_it = m_OriginAppAbbr.find(app); 365 if(abbr_it != m_OriginAppAbbr.end()) 366 app = abbr_it->second; 367 logdata[1] = app; 368 } 369 else 370 logdata[1] = UNKNOWN_ORIGIN; 371 sal_Int32 originwidget_idx = findIdx(args, LOGORIGINWIDGET); 372 if(originwidget_idx!=-1) 373 { 374 OUString widget; 375 args[originwidget_idx].Value >>= widget; 376 map<OUString, OUString>::iterator widget_it = m_OriginWidgetAbbr.find(widget); 377 if(widget_it != m_OriginWidgetAbbr.end()) 378 widget = widget_it->second; 379 logdata[2] = widget; 380 } 381 else 382 logdata[2] = UNKNOWN_ORIGIN; 383 if(url.Complete.match(URL_FILE)) 384 logdata[3] = URL_FILE; 385 else 386 logdata[3] = url.Main; 387 OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s", 388 OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(), 389 OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(), 390 OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(), 391 OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(), 392 OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(), 393 OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(), 394 OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(), 395 OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(), 396 OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr()); 397 m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata)); 398 m_SessionLogEventCount++; 399 } 400 logRotated()401 void UiEventsLogger_Impl::logRotated() 402 { 403 Sequence<OUString> logdata = Sequence<OUString>(COLUMNS); 404 logdata[0] = ETYPE_ROTATED; 405 OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s", 406 OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(), 407 OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(), 408 OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(), 409 OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(), 410 OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(), 411 OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(), 412 OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(), 413 OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(), 414 OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr()); 415 m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata)); 416 } 417 logVcl(const OUString & parent_id,sal_Int32 window_type,const OUString & id,const OUString & method,const OUString & param)418 void UiEventsLogger_Impl::logVcl( 419 const OUString& parent_id, 420 sal_Int32 window_type, 421 const OUString& id, 422 const OUString& method, 423 const OUString& param) 424 { 425 if(!m_Active) return; 426 checkIdleTimeout(); 427 428 OUStringBuffer buf; 429 Sequence<OUString> logdata = Sequence<OUString>(COLUMNS); 430 logdata[0] = ETYPE_VCL; 431 logdata[4] = parent_id; 432 logdata[5] = buf.append(window_type).makeStringAndClear(); 433 logdata[6] = id; 434 logdata[7] = method; 435 logdata[8] = param; 436 OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s", 437 OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(), 438 OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(), 439 OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(), 440 OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(), 441 OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(), 442 OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(), 443 OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(), 444 OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(), 445 OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr()); 446 m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata)); 447 m_SessionLogEventCount++; 448 } 449 rotate()450 void UiEventsLogger_Impl::rotate() 451 { 452 FileBase::RC result = File::move(getCurrentPath(), getRotatedPath()); 453 if(result!=FileBase::E_None && result!=FileBase::E_NOENT) 454 m_Active = false; 455 } 456 hotRotate()457 void UiEventsLogger_Impl::hotRotate() 458 { 459 logRotated(); 460 m_Logger->removeLogHandler(m_LogHandler); 461 m_LogHandler = NULL; 462 rotate(); 463 prepareLogHandler(); 464 if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is()) 465 { 466 m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY)); 467 m_LogHandler->setLevel(LogLevel::ALL); 468 m_Logger->addLogHandler(m_LogHandler); 469 } 470 else 471 m_Active = false; 472 } 473 prepareLogHandler()474 void UiEventsLogger_Impl::prepareLogHandler() 475 { 476 Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); 477 478 Sequence<Any> init_args = Sequence<Any>(1); 479 init_args[0] = static_cast<Any>(getCurrentPath()); 480 Reference< XInterface > temp = 481 sm->createInstanceWithArguments(CSSL_FILEHANDLER, init_args); 482 m_LogHandler = Reference<XLogHandler>(temp, UNO_QUERY); 483 } 484 checkIdleTimeout()485 void UiEventsLogger_Impl::checkIdleTimeout() 486 { 487 TimeValue now; 488 osl_getSystemTime(&now); 489 if(now.Seconds - m_LastLogEventTime.Seconds > m_IdleTimeout.Seconds && m_SessionLogEventCount>0) 490 hotRotate(); 491 m_LastLogEventTime = now; 492 } 493 getCurrentPath()494 OUString UiEventsLogger_Impl::getCurrentPath() 495 { 496 OUStringBuffer current_path(m_LogPath); 497 current_path.appendAscii("/"); 498 current_path.append(FN_CURRENTLOG); 499 current_path.appendAscii(".csv"); 500 return current_path.makeStringAndClear(); 501 } 502 getRotatedPath()503 OUString UiEventsLogger_Impl::getRotatedPath() 504 { 505 OUStringBuffer rotated_path(m_LogPath); 506 rotated_path.appendAscii("/"); 507 rotated_path.append(FN_ROTATEDLOG); 508 rotated_path.appendAscii("-"); 509 { 510 // ISO 8601 511 char tsrotated_pathfer[20]; 512 oslDateTime now; 513 TimeValue now_tv; 514 osl_getSystemTime(&now_tv); 515 osl_getDateTimeFromTimeValue(&now_tv, &now); 516 const size_t rotated_pathfer_size = sizeof(tsrotated_pathfer); 517 snprintf(tsrotated_pathfer, rotated_pathfer_size, "%04i-%02i-%02iT%02i_%02i_%02i", 518 now.Year, 519 now.Month, 520 now.Day, 521 now.Hours, 522 now.Minutes, 523 now.Seconds); 524 rotated_path.appendAscii(tsrotated_pathfer); 525 rotated_path.appendAscii(".csv"); 526 } 527 return rotated_path.makeStringAndClear(); 528 } 529 initializeLogger()530 void UiEventsLogger_Impl::initializeLogger() 531 { 532 Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); 533 534 // getting the Core Uno proxy object 535 // It will call disposing and make sure we clear all our references 536 { 537 Reference<XTerminateListener> xCore( 538 sm->createInstance(OUString::createFromAscii("com.sun.star.oooimprovement.Core")), 539 UNO_QUERY); 540 Reference<XDesktop> xDesktop( 541 sm->createInstance(OUString::createFromAscii("com.sun.star.frame.Desktop")), 542 UNO_QUERY); 543 if(!(xCore.is() && xDesktop.is())) 544 { 545 m_Active = false; 546 return; 547 } 548 xDesktop->addTerminateListener(xCore); 549 } 550 // getting the LoggerPool 551 Reference<XLoggerPool> pool; 552 { 553 Reference<XInterface> temp = 554 sm->createInstance(CSSL_LOGGERPOOL); 555 pool = Reference<XLoggerPool>(temp, UNO_QUERY); 556 } 557 558 // getting the Logger 559 m_Logger = pool->getNamedLogger(LOGGERNAME); 560 561 // getting the FileHandler 562 prepareLogHandler(); 563 564 // getting the Formatter 565 { 566 Reference<XInterface> temp = 567 sm->createInstance(CSSL_CSVFORMATTER); 568 m_Formatter = Reference<XCsvLogFormatter>(temp, UNO_QUERY); 569 } 570 571 if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is()) 572 { 573 Sequence<OUString> columns = Sequence<OUString>(COLUMNS); 574 columns[0] = OUString::createFromAscii("eventtype"); 575 columns[1] = OUString::createFromAscii("originapp"); 576 columns[2] = OUString::createFromAscii("originwidget"); 577 columns[3] = OUString::createFromAscii("uno url"); 578 columns[4] = OUString::createFromAscii("parent id"); 579 columns[5] = OUString::createFromAscii("window type"); 580 columns[6] = OUString::createFromAscii("id"); 581 columns[7] = OUString::createFromAscii("method"); 582 columns[8] = OUString::createFromAscii("parameter"); 583 m_Formatter->setColumnnames(columns); 584 m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY)); 585 m_Logger->setLevel(LogLevel::ALL); 586 m_LogHandler->setLevel(LogLevel::ALL); 587 m_Logger->addLogHandler(m_LogHandler); 588 } 589 else 590 m_Active = false; 591 } 592 593 // private static UiEventsLogger_Impl shouldActivate()594 bool UiEventsLogger_Impl::shouldActivate() 595 { 596 return getEnabledFromCfg() && getEnabledFromCoreController(); 597 } 598 getLogPathFromCfg()599 OUString UiEventsLogger_Impl::getLogPathFromCfg() 600 { 601 OUString result; 602 Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); 603 604 ConfigurationHelper::readDirectKey( 605 sm, 606 CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_LOGPATH, 607 ConfigurationHelper::E_READONLY 608 ) >>= result; 609 610 Reference<XStringSubstitution> path_sub( 611 sm->createInstance(CSSU_PATHSUB), 612 UNO_QUERY); 613 if(path_sub.is()) 614 result = path_sub->substituteVariables(result, sal_False); 615 return result; 616 } 617 getIdleTimeoutFromCfg()618 TimeValue UiEventsLogger_Impl::getIdleTimeoutFromCfg() 619 { 620 sal_Int32 timeoutminutes = 360; 621 Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); 622 623 ConfigurationHelper::readDirectKey( 624 sm, 625 CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_IDLETIMEOUT, 626 ConfigurationHelper::E_READONLY 627 ) >>= timeoutminutes; 628 TimeValue result; 629 result.Seconds = static_cast<sal_uInt32>(timeoutminutes)*60; 630 result.Nanosec = 0; 631 return result; 632 } 633 getEnabledFromCfg()634 bool UiEventsLogger_Impl::getEnabledFromCfg() 635 { 636 sal_Bool result = false; 637 Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); 638 ConfigurationHelper::readDirectKey( 639 sm, 640 CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_ENABLED, 641 ::comphelper::ConfigurationHelper::E_READONLY 642 ) >>= result; 643 return result; 644 } 645 getEnabledFromCoreController()646 bool UiEventsLogger_Impl::getEnabledFromCoreController() 647 { 648 Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); 649 Reference<XCoreController> core_c( 650 sm->createInstance(OUString::createFromAscii("com.sun.star.oooimprovement.CoreController")), 651 UNO_QUERY); 652 if(!core_c.is()) return false; 653 return core_c->enablingUiEventsLoggerAllowed(1); 654 } 655 656 UiEventsLogger_Impl::ptr UiEventsLogger_Impl::instance = UiEventsLogger_Impl::ptr(); getInstance()657 UiEventsLogger_Impl::ptr UiEventsLogger_Impl::getInstance() 658 { 659 if(instance == NULL) 660 instance = UiEventsLogger_Impl::ptr(new UiEventsLogger_Impl()); 661 return instance; 662 } 663 664 Mutex * UiEventsLogger_Impl::singleton_mutex = NULL; prepareMutex()665 void UiEventsLogger_Impl::prepareMutex() 666 { 667 if(singleton_mutex == NULL) 668 { 669 Guard<Mutex> global_guard(Mutex::getGlobalMutex()); 670 if(singleton_mutex == NULL) 671 singleton_mutex = new Mutex(); 672 } 673 } 674 findIdx(const Sequence<PropertyValue> & args,const OUString & key)675 sal_Int32 UiEventsLogger_Impl::findIdx(const Sequence<PropertyValue>& args, const OUString& key) 676 { 677 for(sal_Int32 i=0; i<args.getLength(); i++) 678 if(args[i].Name == key) 679 return i; 680 return -1; 681 } 682 disposing()683 void UiEventsLogger_Impl::disposing() 684 { 685 m_Active = false; 686 m_Logger.clear() ; 687 m_LogHandler.clear(); 688 m_Formatter.clear(); 689 } 690 } 691