| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_comphelper.hxx" |
| |
| #include <comphelper/uieventslogger.hxx> |
| #include <boost/shared_ptr.hpp> |
| #include <com/sun/star/frame/XDesktop.hpp> |
| #include <com/sun/star/frame/XTerminateListener.hpp> |
| #include <com/sun/star/lang/XEventListener.hpp> |
| #include <com/sun/star/lang/XMultiComponentFactory.hpp> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/logging/LogLevel.hpp> |
| #include <com/sun/star/logging/XCsvLogFormatter.hpp> |
| #include <com/sun/star/logging/XLogHandler.hpp> |
| #include <com/sun/star/logging/XLogger.hpp> |
| #include <com/sun/star/logging/XLoggerPool.hpp> |
| #include <com/sun/star/oooimprovement/XCoreController.hpp> |
| #include <com/sun/star/uno/Sequence.hxx> |
| #include <com/sun/star/util/XStringSubstitution.hpp> |
| #include <comphelper/configurationhelper.hxx> |
| #include <comphelper/processfactory.hxx> |
| #include <map> |
| #include <osl/file.hxx> |
| #include <osl/mutex.hxx> |
| #include <osl/time.h> |
| #include <rtl/ustrbuf.hxx> |
| |
| |
| using namespace com::sun::star::beans; |
| using namespace com::sun::star::frame; |
| using namespace com::sun::star::lang; |
| using namespace com::sun::star::logging; |
| using namespace com::sun::star::oooimprovement; |
| using namespace com::sun::star::uno; |
| using namespace com::sun::star::util; |
| using namespace cppu; |
| using namespace osl; |
| using namespace rtl; |
| using namespace std; |
| |
| |
| namespace |
| { |
| static void lcl_SetupOriginAppAbbr(map<OUString, OUString>& abbrs) |
| { |
| abbrs[OUString::createFromAscii("com.sun.star.text.TextDocument")] = OUString::createFromAscii("W"); // Writer |
| abbrs[OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument")] = OUString::createFromAscii("C"); // Calc |
| abbrs[OUString::createFromAscii("com.sun.star.presentation.PresentationDocument")] = OUString::createFromAscii("I"); // Impress |
| abbrs[OUString::createFromAscii("com.sun.star.drawing.DrawingDocument")] = OUString::createFromAscii("D"); // Draw |
| }; |
| |
| static void lcl_SetupOriginWidgetAbbr(map<OUString,OUString>& abbrs) |
| { |
| abbrs[OUString::createFromAscii("ButtonToolbarController")] = OUString::createFromAscii("0"); |
| abbrs[OUString::createFromAscii("ComplexToolbarController")] = OUString::createFromAscii("1"); |
| abbrs[OUString::createFromAscii("ControlMenuController")] = OUString::createFromAscii("2"); |
| abbrs[OUString::createFromAscii("FontMenuController")] = OUString::createFromAscii("3"); |
| abbrs[OUString::createFromAscii("FontSizeMenuController")] = OUString::createFromAscii("4"); |
| abbrs[OUString::createFromAscii("FooterMenuController")] = OUString::createFromAscii("5"); |
| abbrs[OUString::createFromAscii("GenericToolbarController")] = OUString::createFromAscii("6"); |
| abbrs[OUString::createFromAscii("HeaderMenuController")] = OUString::createFromAscii("7"); |
| abbrs[OUString::createFromAscii("LanguageSelectionMenuController")] = OUString::createFromAscii("8"); |
| abbrs[OUString::createFromAscii("LangSelectionStatusbarController")] = OUString::createFromAscii("9"); |
| abbrs[OUString::createFromAscii("MacrosMenuController")] = OUString::createFromAscii("10"); |
| abbrs[OUString::createFromAscii("MenuBarManager")] = OUString::createFromAscii("11"); |
| abbrs[OUString::createFromAscii("NewMenuController")] = OUString::createFromAscii("12"); |
| abbrs[OUString::createFromAscii("ObjectMenuController")] = OUString::createFromAscii("13"); |
| abbrs[OUString::createFromAscii("RecentFilesMenuController")] = OUString::createFromAscii("14"); |
| abbrs[OUString::createFromAscii("ToolbarsMenuController")] = OUString::createFromAscii("15"); |
| abbrs[OUString::createFromAscii("SfxToolBoxControl")] = OUString::createFromAscii("16"); |
| abbrs[OUString::createFromAscii("SfxAsyncExec")] = OUString::createFromAscii("17"); |
| abbrs[OUString::createFromAscii("AcceleratorExecute")] = OUString::createFromAscii("18"); |
| }; |
| } |
| |
| namespace comphelper |
| { |
| // declaration of implementation |
| class UiEventsLogger_Impl; |
| class UiEventsLogger_Impl : public UiEventsLogger |
| { |
| private: |
| //typedefs and friends |
| friend class UiEventsLogger; |
| typedef UiEventsLogger_Impl* ptr; |
| |
| // instance methods and data |
| UiEventsLogger_Impl(); |
| void initializeLogger(); |
| void logDispatch(const ::com::sun::star::util::URL& url, |
| const Sequence<PropertyValue>& args); |
| void logRotated(); |
| void logVcl(const ::rtl::OUString& parent_id, |
| sal_Int32 window_type, |
| const ::rtl::OUString& id, |
| const ::rtl::OUString& method, |
| const ::rtl::OUString& param); |
| void rotate(); |
| void hotRotate(); |
| void prepareLogHandler(); |
| void checkIdleTimeout(); |
| OUString getCurrentPath(); |
| OUString getRotatedPath(); |
| void disposing(); |
| |
| bool m_Active; |
| TimeValue m_LastLogEventTime; |
| const OUString m_LogPath; |
| const TimeValue m_IdleTimeout; |
| sal_Int32 m_SessionLogEventCount; |
| Reference<XLogger> m_Logger; |
| Reference<XLogHandler> m_LogHandler; |
| Reference<XCsvLogFormatter> m_Formatter; |
| map<OUString, OUString> m_OriginAppAbbr; |
| map<OUString, OUString> m_OriginWidgetAbbr; |
| |
| |
| // static methods and data |
| static ptr getInstance(); |
| static void prepareMutex(); |
| static bool shouldActivate(); |
| static bool getEnabledFromCoreController(); |
| static bool getEnabledFromCfg(); |
| static TimeValue getIdleTimeoutFromCfg(); |
| static OUString getLogPathFromCfg(); |
| static sal_Int32 findIdx(const Sequence<PropertyValue>& args, const OUString& key); |
| |
| static ptr instance; |
| static Mutex * singleton_mutex; |
| static const sal_Int32 COLUMNS; |
| static const OUString CFG_ENABLED; |
| static const OUString CFG_IDLETIMEOUT; |
| static const OUString CFG_LOGGING; |
| static const OUString CFG_LOGPATH; |
| static const OUString CFG_OOOIMPROVEMENT; |
| static const OUString ETYPE_DISPATCH; |
| static const OUString ETYPE_ROTATED; |
| static const OUString ETYPE_VCL; |
| static const OUString CSSL_CSVFORMATTER; |
| static const OUString CSSL_FILEHANDLER; |
| static const OUString CSSL_LOGGERPOOL; |
| static const OUString CSSO_CORECONTROLLER; |
| static const OUString CSST_JOBEXECUTOR; |
| static const OUString CSSU_PATHSUB; |
| static const OUString LOGGERNAME; |
| static const OUString LOGORIGINAPP; |
| static const OUString LOGORIGINWIDGET; |
| static const OUString UNKNOWN_ORIGIN; |
| static const OUString FN_CURRENTLOG; |
| static const OUString FN_ROTATEDLOG; |
| static const OUString LOGROTATE_EVENTNAME; |
| static const OUString URL_UNO; |
| static const OUString URL_SPECIAL; |
| static const OUString URL_FILE; |
| }; |
| } |
| |
| namespace comphelper |
| { |
| // consts |
| const sal_Int32 UiEventsLogger_Impl::COLUMNS = 9; |
| const OUString UiEventsLogger_Impl::CFG_ENABLED = OUString::createFromAscii("EnablingAllowed"); |
| const OUString UiEventsLogger_Impl::CFG_IDLETIMEOUT = OUString::createFromAscii("IdleTimeout"); |
| const OUString UiEventsLogger_Impl::CFG_LOGGING = OUString::createFromAscii("/org.openoffice.Office.Logging"); |
| const OUString UiEventsLogger_Impl::CFG_LOGPATH = OUString::createFromAscii("LogPath"); |
| const OUString UiEventsLogger_Impl::CFG_OOOIMPROVEMENT = OUString::createFromAscii("OOoImprovement"); |
| |
| const OUString UiEventsLogger_Impl::CSSL_CSVFORMATTER = OUString::createFromAscii("com.sun.star.logging.CsvFormatter"); |
| const OUString UiEventsLogger_Impl::CSSL_FILEHANDLER = OUString::createFromAscii("com.sun.star.logging.FileHandler"); |
| const OUString UiEventsLogger_Impl::CSSL_LOGGERPOOL = OUString::createFromAscii("com.sun.star.logging.LoggerPool"); |
| const OUString UiEventsLogger_Impl::CSSO_CORECONTROLLER = OUString::createFromAscii("com.sun.star.oooimprovement.CoreController"); |
| const OUString UiEventsLogger_Impl::CSSU_PATHSUB = OUString::createFromAscii("com.sun.star.util.PathSubstitution"); |
| |
| const OUString UiEventsLogger_Impl::ETYPE_DISPATCH = OUString::createFromAscii("dispatch"); |
| const OUString UiEventsLogger_Impl::ETYPE_ROTATED = OUString::createFromAscii("rotated"); |
| const OUString UiEventsLogger_Impl::ETYPE_VCL = OUString::createFromAscii("vcl"); |
| |
| const OUString UiEventsLogger_Impl::LOGGERNAME = OUString::createFromAscii("org.openoffice.oooimprovement.Core.UiEventsLogger"); |
| const OUString UiEventsLogger_Impl::LOGORIGINWIDGET = OUString::createFromAscii("comphelper.UiEventsLogger.LogOriginWidget"); |
| const OUString UiEventsLogger_Impl::LOGORIGINAPP = OUString::createFromAscii("comphelper.UiEventsLogger.LogOriginApp"); |
| |
| const OUString UiEventsLogger_Impl::UNKNOWN_ORIGIN = OUString::createFromAscii("unknown origin"); |
| const OUString UiEventsLogger_Impl::FN_CURRENTLOG = OUString::createFromAscii("Current"); |
| const OUString UiEventsLogger_Impl::FN_ROTATEDLOG = OUString::createFromAscii("OOoImprove"); |
| const OUString UiEventsLogger_Impl::LOGROTATE_EVENTNAME = OUString::createFromAscii("onOOoImprovementLogRotated"); |
| |
| const OUString UiEventsLogger_Impl::URL_UNO = OUString::createFromAscii(".uno:"); |
| const OUString UiEventsLogger_Impl::URL_SPECIAL = OUString::createFromAscii(".special:"); |
| const OUString UiEventsLogger_Impl::URL_FILE = OUString::createFromAscii("file:"); |
| |
| |
| // public UiEventsLogger interface |
| sal_Bool UiEventsLogger::isEnabled() |
| { |
| if ( UiEventsLogger_Impl::getEnabledFromCfg() ) |
| { |
| try { |
| UiEventsLogger_Impl::prepareMutex(); |
| Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); |
| return UiEventsLogger_Impl::getInstance()->m_Active; |
| } catch(...) { return false; } // never throws |
| } // if ( ) |
| return sal_False; |
| } |
| |
| sal_Int32 UiEventsLogger::getSessionLogEventCount() |
| { |
| try { |
| UiEventsLogger_Impl::prepareMutex(); |
| Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); |
| return UiEventsLogger_Impl::getInstance()->m_SessionLogEventCount; |
| } catch(...) { return 0; } // never throws |
| } |
| |
| void UiEventsLogger::appendDispatchOrigin( |
| Sequence<PropertyValue>& args, |
| const OUString& originapp, |
| const OUString& originwidget) |
| { |
| sal_Int32 old_length = args.getLength(); |
| args.realloc(old_length+2); |
| args[old_length].Name = UiEventsLogger_Impl::LOGORIGINAPP; |
| args[old_length].Value = static_cast<Any>(originapp); |
| args[old_length+1].Name = UiEventsLogger_Impl::LOGORIGINWIDGET; |
| args[old_length+1].Value = static_cast<Any>(originwidget); |
| } |
| |
| Sequence<PropertyValue> UiEventsLogger::purgeDispatchOrigin( |
| const Sequence<PropertyValue>& args) |
| { |
| Sequence<PropertyValue> result(args.getLength()); |
| sal_Int32 target_idx=0; |
| for(sal_Int32 source_idx=0; source_idx<args.getLength(); source_idx++) |
| if(args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINAPP |
| && args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINWIDGET) |
| result[target_idx++] = args[source_idx]; |
| result.realloc(target_idx); |
| return result; |
| } |
| |
| void UiEventsLogger::logDispatch( |
| const URL& url, |
| const Sequence<PropertyValue>& args) |
| { |
| try { |
| UiEventsLogger_Impl::prepareMutex(); |
| Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); |
| UiEventsLogger_Impl::getInstance()->logDispatch(url, args); |
| } catch(...) { } // never throws |
| } |
| |
| void UiEventsLogger::logVcl( |
| const OUString& parent_id, |
| sal_Int32 window_type, |
| const OUString& id, |
| const OUString& method, |
| const OUString& param) |
| { |
| try { |
| UiEventsLogger_Impl::prepareMutex(); |
| Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); |
| UiEventsLogger_Impl::getInstance()->logVcl(parent_id, window_type, id, method, param); |
| } catch(...) { } // never throws |
| } |
| |
| void UiEventsLogger::logVcl( |
| const OUString& parent_id, |
| sal_Int32 window_type, |
| const OUString& id, |
| const OUString& method, |
| sal_Int32 param) |
| { |
| OUStringBuffer buf; |
| UiEventsLogger::logVcl(parent_id, window_type, id, method, buf.append(param).makeStringAndClear()); |
| } |
| |
| void UiEventsLogger::logVcl( |
| const OUString& parent_id, |
| sal_Int32 window_type, |
| const OUString& id, |
| const OUString& method) |
| { |
| OUString empty; |
| UiEventsLogger::logVcl(parent_id, window_type, id, method, empty); |
| } |
| |
| void UiEventsLogger::disposing() |
| { |
| // we dont want to create an instance just to dispose it |
| UiEventsLogger_Impl::prepareMutex(); |
| Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); |
| if(UiEventsLogger_Impl::instance!=UiEventsLogger_Impl::ptr()) |
| UiEventsLogger_Impl::getInstance()->disposing(); |
| } |
| |
| void UiEventsLogger::reinit() |
| { |
| UiEventsLogger_Impl::prepareMutex(); |
| Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex); |
| if(UiEventsLogger_Impl::instance) |
| { |
| UiEventsLogger_Impl::instance->disposing(); |
| delete UiEventsLogger_Impl::instance; |
| UiEventsLogger_Impl::instance = NULL; |
| } |
| } |
| |
| // private UiEventsLogger_Impl methods |
| UiEventsLogger_Impl::UiEventsLogger_Impl() |
| : m_Active(UiEventsLogger_Impl::shouldActivate()) |
| , m_LogPath(UiEventsLogger_Impl::getLogPathFromCfg()) |
| , m_IdleTimeout(UiEventsLogger_Impl::getIdleTimeoutFromCfg()) |
| , m_SessionLogEventCount(0) |
| { |
| lcl_SetupOriginAppAbbr(m_OriginAppAbbr); |
| lcl_SetupOriginWidgetAbbr(m_OriginWidgetAbbr); |
| m_LastLogEventTime.Seconds = m_LastLogEventTime.Nanosec = 0; |
| if(m_Active) rotate(); |
| if(m_Active) initializeLogger(); |
| } |
| |
| void UiEventsLogger_Impl::logDispatch( |
| const URL& url, |
| const Sequence<PropertyValue>& args) |
| { |
| if(!m_Active) return; |
| if(!url.Complete.match(URL_UNO) |
| && !url.Complete.match(URL_FILE) |
| && !url.Complete.match(URL_SPECIAL)) |
| { |
| return; |
| } |
| checkIdleTimeout(); |
| |
| Sequence<OUString> logdata = Sequence<OUString>(COLUMNS); |
| logdata[0] = ETYPE_DISPATCH; |
| sal_Int32 originapp_idx = findIdx(args, LOGORIGINAPP); |
| if(originapp_idx!=-1) |
| { |
| OUString app; |
| args[originapp_idx].Value >>= app; |
| map<OUString, OUString>::iterator abbr_it = m_OriginAppAbbr.find(app); |
| if(abbr_it != m_OriginAppAbbr.end()) |
| app = abbr_it->second; |
| logdata[1] = app; |
| } |
| else |
| logdata[1] = UNKNOWN_ORIGIN; |
| sal_Int32 originwidget_idx = findIdx(args, LOGORIGINWIDGET); |
| if(originwidget_idx!=-1) |
| { |
| OUString widget; |
| args[originwidget_idx].Value >>= widget; |
| map<OUString, OUString>::iterator widget_it = m_OriginWidgetAbbr.find(widget); |
| if(widget_it != m_OriginWidgetAbbr.end()) |
| widget = widget_it->second; |
| logdata[2] = widget; |
| } |
| else |
| logdata[2] = UNKNOWN_ORIGIN; |
| if(url.Complete.match(URL_FILE)) |
| logdata[3] = URL_FILE; |
| else |
| logdata[3] = url.Main; |
| OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s", |
| OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr()); |
| m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata)); |
| m_SessionLogEventCount++; |
| } |
| |
| void UiEventsLogger_Impl::logRotated() |
| { |
| Sequence<OUString> logdata = Sequence<OUString>(COLUMNS); |
| logdata[0] = ETYPE_ROTATED; |
| OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s", |
| OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr()); |
| m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata)); |
| } |
| |
| void UiEventsLogger_Impl::logVcl( |
| const OUString& parent_id, |
| sal_Int32 window_type, |
| const OUString& id, |
| const OUString& method, |
| const OUString& param) |
| { |
| if(!m_Active) return; |
| checkIdleTimeout(); |
| |
| OUStringBuffer buf; |
| Sequence<OUString> logdata = Sequence<OUString>(COLUMNS); |
| logdata[0] = ETYPE_VCL; |
| logdata[4] = parent_id; |
| logdata[5] = buf.append(window_type).makeStringAndClear(); |
| logdata[6] = id; |
| logdata[7] = method; |
| logdata[8] = param; |
| OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s", |
| OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(), |
| OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr()); |
| m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata)); |
| m_SessionLogEventCount++; |
| } |
| |
| void UiEventsLogger_Impl::rotate() |
| { |
| FileBase::RC result = File::move(getCurrentPath(), getRotatedPath()); |
| if(result!=FileBase::E_None && result!=FileBase::E_NOENT) |
| m_Active = false; |
| } |
| |
| void UiEventsLogger_Impl::hotRotate() |
| { |
| logRotated(); |
| m_Logger->removeLogHandler(m_LogHandler); |
| m_LogHandler = NULL; |
| rotate(); |
| prepareLogHandler(); |
| if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is()) |
| { |
| m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY)); |
| m_LogHandler->setLevel(LogLevel::ALL); |
| m_Logger->addLogHandler(m_LogHandler); |
| } |
| else |
| m_Active = false; |
| } |
| |
| void UiEventsLogger_Impl::prepareLogHandler() |
| { |
| Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); |
| |
| Sequence<Any> init_args = Sequence<Any>(1); |
| init_args[0] = static_cast<Any>(getCurrentPath()); |
| Reference< XInterface > temp = |
| sm->createInstanceWithArguments(CSSL_FILEHANDLER, init_args); |
| m_LogHandler = Reference<XLogHandler>(temp, UNO_QUERY); |
| } |
| |
| void UiEventsLogger_Impl::checkIdleTimeout() |
| { |
| TimeValue now; |
| osl_getSystemTime(&now); |
| if(now.Seconds - m_LastLogEventTime.Seconds > m_IdleTimeout.Seconds && m_SessionLogEventCount>0) |
| hotRotate(); |
| m_LastLogEventTime = now; |
| } |
| |
| OUString UiEventsLogger_Impl::getCurrentPath() |
| { |
| OUStringBuffer current_path(m_LogPath); |
| current_path.appendAscii("/"); |
| current_path.append(FN_CURRENTLOG); |
| current_path.appendAscii(".csv"); |
| return current_path.makeStringAndClear(); |
| } |
| |
| OUString UiEventsLogger_Impl::getRotatedPath() |
| { |
| OUStringBuffer rotated_path(m_LogPath); |
| rotated_path.appendAscii("/"); |
| rotated_path.append(FN_ROTATEDLOG); |
| rotated_path.appendAscii("-"); |
| { |
| // ISO 8601 |
| char tsrotated_pathfer[20]; |
| oslDateTime now; |
| TimeValue now_tv; |
| osl_getSystemTime(&now_tv); |
| osl_getDateTimeFromTimeValue(&now_tv, &now); |
| const size_t rotated_pathfer_size = sizeof(tsrotated_pathfer); |
| snprintf(tsrotated_pathfer, rotated_pathfer_size, "%04i-%02i-%02iT%02i_%02i_%02i", |
| now.Year, |
| now.Month, |
| now.Day, |
| now.Hours, |
| now.Minutes, |
| now.Seconds); |
| rotated_path.appendAscii(tsrotated_pathfer); |
| rotated_path.appendAscii(".csv"); |
| } |
| return rotated_path.makeStringAndClear(); |
| } |
| |
| void UiEventsLogger_Impl::initializeLogger() |
| { |
| Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); |
| |
| // getting the Core Uno proxy object |
| // It will call disposing and make sure we clear all our references |
| { |
| Reference<XTerminateListener> xCore( |
| sm->createInstance(OUString::createFromAscii("com.sun.star.oooimprovement.Core")), |
| UNO_QUERY); |
| Reference<XDesktop> xDesktop( |
| sm->createInstance(OUString::createFromAscii("com.sun.star.frame.Desktop")), |
| UNO_QUERY); |
| if(!(xCore.is() && xDesktop.is())) |
| { |
| m_Active = false; |
| return; |
| } |
| xDesktop->addTerminateListener(xCore); |
| } |
| // getting the LoggerPool |
| Reference<XLoggerPool> pool; |
| { |
| Reference<XInterface> temp = |
| sm->createInstance(CSSL_LOGGERPOOL); |
| pool = Reference<XLoggerPool>(temp, UNO_QUERY); |
| } |
| |
| // getting the Logger |
| m_Logger = pool->getNamedLogger(LOGGERNAME); |
| |
| // getting the FileHandler |
| prepareLogHandler(); |
| |
| // getting the Formatter |
| { |
| Reference<XInterface> temp = |
| sm->createInstance(CSSL_CSVFORMATTER); |
| m_Formatter = Reference<XCsvLogFormatter>(temp, UNO_QUERY); |
| } |
| |
| if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is()) |
| { |
| Sequence<OUString> columns = Sequence<OUString>(COLUMNS); |
| columns[0] = OUString::createFromAscii("eventtype"); |
| columns[1] = OUString::createFromAscii("originapp"); |
| columns[2] = OUString::createFromAscii("originwidget"); |
| columns[3] = OUString::createFromAscii("uno url"); |
| columns[4] = OUString::createFromAscii("parent id"); |
| columns[5] = OUString::createFromAscii("window type"); |
| columns[6] = OUString::createFromAscii("id"); |
| columns[7] = OUString::createFromAscii("method"); |
| columns[8] = OUString::createFromAscii("parameter"); |
| m_Formatter->setColumnnames(columns); |
| m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY)); |
| m_Logger->setLevel(LogLevel::ALL); |
| m_LogHandler->setLevel(LogLevel::ALL); |
| m_Logger->addLogHandler(m_LogHandler); |
| } |
| else |
| m_Active = false; |
| } |
| |
| // private static UiEventsLogger_Impl |
| bool UiEventsLogger_Impl::shouldActivate() |
| { |
| return getEnabledFromCfg() && getEnabledFromCoreController(); |
| } |
| |
| OUString UiEventsLogger_Impl::getLogPathFromCfg() |
| { |
| OUString result; |
| Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); |
| |
| ConfigurationHelper::readDirectKey( |
| sm, |
| CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_LOGPATH, |
| ConfigurationHelper::E_READONLY |
| ) >>= result; |
| |
| Reference<XStringSubstitution> path_sub( |
| sm->createInstance(CSSU_PATHSUB), |
| UNO_QUERY); |
| if(path_sub.is()) |
| result = path_sub->substituteVariables(result, sal_False); |
| return result; |
| } |
| |
| TimeValue UiEventsLogger_Impl::getIdleTimeoutFromCfg() |
| { |
| sal_Int32 timeoutminutes = 360; |
| Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); |
| |
| ConfigurationHelper::readDirectKey( |
| sm, |
| CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_IDLETIMEOUT, |
| ConfigurationHelper::E_READONLY |
| ) >>= timeoutminutes; |
| TimeValue result; |
| result.Seconds = static_cast<sal_uInt32>(timeoutminutes)*60; |
| result.Nanosec = 0; |
| return result; |
| } |
| |
| bool UiEventsLogger_Impl::getEnabledFromCfg() |
| { |
| sal_Bool result = false; |
| Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); |
| ConfigurationHelper::readDirectKey( |
| sm, |
| CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_ENABLED, |
| ::comphelper::ConfigurationHelper::E_READONLY |
| ) >>= result; |
| return result; |
| } |
| |
| bool UiEventsLogger_Impl::getEnabledFromCoreController() |
| { |
| Reference<XMultiServiceFactory> sm = getProcessServiceFactory(); |
| Reference<XCoreController> core_c( |
| sm->createInstance(OUString::createFromAscii("com.sun.star.oooimprovement.CoreController")), |
| UNO_QUERY); |
| if(!core_c.is()) return false; |
| return core_c->enablingUiEventsLoggerAllowed(1); |
| } |
| |
| UiEventsLogger_Impl::ptr UiEventsLogger_Impl::instance = UiEventsLogger_Impl::ptr(); |
| UiEventsLogger_Impl::ptr UiEventsLogger_Impl::getInstance() |
| { |
| if(instance == NULL) |
| instance = UiEventsLogger_Impl::ptr(new UiEventsLogger_Impl()); |
| return instance; |
| } |
| |
| Mutex * UiEventsLogger_Impl::singleton_mutex = NULL; |
| void UiEventsLogger_Impl::prepareMutex() |
| { |
| if(singleton_mutex == NULL) |
| { |
| Guard<Mutex> global_guard(Mutex::getGlobalMutex()); |
| if(singleton_mutex == NULL) |
| singleton_mutex = new Mutex(); |
| } |
| } |
| |
| sal_Int32 UiEventsLogger_Impl::findIdx(const Sequence<PropertyValue>& args, const OUString& key) |
| { |
| for(sal_Int32 i=0; i<args.getLength(); i++) |
| if(args[i].Name == key) |
| return i; |
| return -1; |
| } |
| |
| void UiEventsLogger_Impl::disposing() |
| { |
| m_Active = false; |
| m_Logger.clear() ; |
| m_LogHandler.clear(); |
| m_Formatter.clear(); |
| } |
| } |