diff options
Diffstat (limited to 'extensions/source/logging')
-rw-r--r-- | extensions/source/logging/consolehandler.cxx | 342 | ||||
-rw-r--r-- | extensions/source/logging/csvformatter.cxx | 382 | ||||
-rw-r--r-- | extensions/source/logging/filehandler.cxx | 441 | ||||
-rw-r--r-- | extensions/source/logging/log.component | 47 | ||||
-rw-r--r-- | extensions/source/logging/log_module.cxx | 43 | ||||
-rw-r--r-- | extensions/source/logging/log_module.hxx | 45 | ||||
-rw-r--r-- | extensions/source/logging/log_services.cxx | 69 | ||||
-rw-r--r-- | extensions/source/logging/logger.cxx | 404 | ||||
-rw-r--r-- | extensions/source/logging/loggerconfig.cxx | 283 | ||||
-rw-r--r-- | extensions/source/logging/loggerconfig.hxx | 65 | ||||
-rw-r--r-- | extensions/source/logging/loghandler.cxx | 204 | ||||
-rw-r--r-- | extensions/source/logging/loghandler.hxx | 154 | ||||
-rw-r--r-- | extensions/source/logging/logrecord.cxx | 103 | ||||
-rw-r--r-- | extensions/source/logging/logrecord.hxx | 68 | ||||
-rw-r--r-- | extensions/source/logging/makefile.mk | 84 | ||||
-rw-r--r-- | extensions/source/logging/methodguard.hxx | 73 | ||||
-rw-r--r-- | extensions/source/logging/plaintextformatter.cxx | 226 |
17 files changed, 3033 insertions, 0 deletions
diff --git a/extensions/source/logging/consolehandler.cxx b/extensions/source/logging/consolehandler.cxx new file mode 100644 index 000000000000..36e3fbb0c21d --- /dev/null +++ b/extensions/source/logging/consolehandler.cxx @@ -0,0 +1,342 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#include "log_module.hxx" +#include "methodguard.hxx" +#include "loghandler.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/logging/XConsoleHandler.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/logging/LogLevel.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/ucb/AlreadyInitializedException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +/** === end UNO includes === **/ + +#include <tools/diagnose_ex.h> + +#include <comphelper/componentcontext.hxx> + +#include <cppuhelper/compbase3.hxx> +#include <cppuhelper/basemutex.hxx> + +#include <stdio.h> + +//........................................................................ +namespace logging +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::logging::XConsoleHandler; + using ::com::sun::star::lang::XServiceInfo; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::logging::XLogFormatter; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::logging::LogRecord; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::lang::XInitialization; + using ::com::sun::star::ucb::AlreadyInitializedException; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::beans::NamedValue; + /** === end UNO using === **/ + namespace LogLevel = ::com::sun::star::logging::LogLevel; + + //==================================================================== + //= ConsoleHandler - declaration + //==================================================================== + //-------------------------------------------------------------------- + typedef ::cppu::WeakComponentImplHelper3 < XConsoleHandler + , XServiceInfo + , XInitialization + > ConsoleHandler_Base; + class ConsoleHandler :public ::cppu::BaseMutex + ,public ConsoleHandler_Base + { + private: + ::comphelper::ComponentContext m_aContext; + LogHandlerHelper m_aHandlerHelper; + sal_Int32 m_nThreshold; + + protected: + ConsoleHandler( const Reference< XComponentContext >& _rxContext ); + virtual ~ConsoleHandler(); + + // XConsoleHandler + virtual ::sal_Int32 SAL_CALL getThreshold() throw (RuntimeException); + virtual void SAL_CALL setThreshold( ::sal_Int32 _threshold ) throw (RuntimeException); + + // XLogHandler + virtual ::rtl::OUString SAL_CALL getEncoding() throw (RuntimeException); + virtual void SAL_CALL setEncoding( const ::rtl::OUString& _encoding ) throw (RuntimeException); + virtual Reference< XLogFormatter > SAL_CALL getFormatter() throw (RuntimeException); + virtual void SAL_CALL setFormatter( const Reference< XLogFormatter >& _formatter ) throw (RuntimeException); + virtual ::sal_Int32 SAL_CALL getLevel() throw (RuntimeException); + virtual void SAL_CALL setLevel( ::sal_Int32 _level ) throw (RuntimeException); + virtual void SAL_CALL flush( ) throw (RuntimeException); + virtual ::sal_Bool SAL_CALL publish( const LogRecord& Record ) throw (RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException); + virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); + + // OComponentHelper + virtual void SAL_CALL disposing(); + + public: + // XServiceInfo - static version + static ::rtl::OUString SAL_CALL getImplementationName_static(); + static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext ); + + public: + typedef ComponentMethodGuard< ConsoleHandler > MethodGuard; + void enterMethod( MethodGuard::Access ); + void leaveMethod( MethodGuard::Access ); + }; + + //==================================================================== + //= ConsoleHandler - implementation + //==================================================================== + //-------------------------------------------------------------------- + ConsoleHandler::ConsoleHandler( const Reference< XComponentContext >& _rxContext ) + :ConsoleHandler_Base( m_aMutex ) + ,m_aContext( _rxContext ) + ,m_aHandlerHelper( _rxContext, m_aMutex, rBHelper ) + ,m_nThreshold( LogLevel::SEVERE ) + { + } + + //-------------------------------------------------------------------- + ConsoleHandler::~ConsoleHandler() + { + if ( !rBHelper.bDisposed ) + { + acquire(); + dispose(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL ConsoleHandler::disposing() + { + m_aHandlerHelper.setFormatter( NULL ); + } + + //-------------------------------------------------------------------- + void ConsoleHandler::enterMethod( MethodGuard::Access ) + { + m_aHandlerHelper.enterMethod(); + } + + //-------------------------------------------------------------------- + void ConsoleHandler::leaveMethod( MethodGuard::Access ) + { + m_aMutex.release(); + } + + //-------------------------------------------------------------------- + ::sal_Int32 SAL_CALL ConsoleHandler::getThreshold() throw (RuntimeException) + { + MethodGuard aGuard( *this ); + return m_nThreshold; + } + + //-------------------------------------------------------------------- + void SAL_CALL ConsoleHandler::setThreshold( ::sal_Int32 _threshold ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + m_nThreshold = _threshold; + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL ConsoleHandler::getEncoding() throw (RuntimeException) + { + MethodGuard aGuard( *this ); + ::rtl::OUString sEncoding; + OSL_VERIFY( m_aHandlerHelper.getEncoding( sEncoding ) ); + return sEncoding; + } + + //-------------------------------------------------------------------- + void SAL_CALL ConsoleHandler::setEncoding( const ::rtl::OUString& _rEncoding ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + OSL_VERIFY( m_aHandlerHelper.setEncoding( _rEncoding ) ); + } + + //-------------------------------------------------------------------- + Reference< XLogFormatter > SAL_CALL ConsoleHandler::getFormatter() throw (RuntimeException) + { + MethodGuard aGuard( *this ); + return m_aHandlerHelper.getFormatter(); + } + + //-------------------------------------------------------------------- + void SAL_CALL ConsoleHandler::setFormatter( const Reference< XLogFormatter >& _rxFormatter ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + m_aHandlerHelper.setFormatter( _rxFormatter ); + } + + //-------------------------------------------------------------------- + ::sal_Int32 SAL_CALL ConsoleHandler::getLevel() throw (RuntimeException) + { + MethodGuard aGuard( *this ); + return m_aHandlerHelper.getLevel(); + } + + //-------------------------------------------------------------------- + void SAL_CALL ConsoleHandler::setLevel( ::sal_Int32 _nLevel ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + m_aHandlerHelper.setLevel( _nLevel ); + } + + //-------------------------------------------------------------------- + void SAL_CALL ConsoleHandler::flush( ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + fflush( stdout ); + fflush( stderr ); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL ConsoleHandler::publish( const LogRecord& _rRecord ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + + ::rtl::OString sEntry; + if ( !m_aHandlerHelper.formatForPublishing( _rRecord, sEntry ) ) + return sal_False; + + if ( _rRecord.Level >= m_nThreshold ) + fprintf( stderr, sEntry.getStr() ); + else + fprintf( stdout, sEntry.getStr() ); + + return sal_True; + } + + //-------------------------------------------------------------------- + void SAL_CALL ConsoleHandler::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_aHandlerHelper.getIsInitialized() ) + throw AlreadyInitializedException(); + + if ( _rArguments.getLength() == 0 ) + { // create() - nothing to init + m_aHandlerHelper.setIsInitialized(); + return; + } + + if ( _rArguments.getLength() != 1 ) + throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); + + Sequence< NamedValue > aSettings; + if ( !( _rArguments[0] >>= aSettings ) ) + throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); + + // createWithSettings( [in] sequence< ::com::sun::star::beans::NamedValue > Settings ) + ::comphelper::NamedValueCollection aTypedSettings( aSettings ); + m_aHandlerHelper.initFromSettings( aTypedSettings ); + + aTypedSettings.get_ensureType( "Threshold", m_nThreshold ); + + m_aHandlerHelper.setIsInitialized(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL ConsoleHandler::getImplementationName() throw(RuntimeException) + { + return getImplementationName_static(); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL ConsoleHandler::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException) + { + const Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames() ); + for ( const ::rtl::OUString* pServiceNames = aServiceNames.getConstArray(); + pServiceNames != aServiceNames.getConstArray() + aServiceNames.getLength(); + ++pServiceNames + ) + if ( _rServiceName == *pServiceNames ) + return sal_True; + return sal_False; + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL ConsoleHandler::getSupportedServiceNames() throw(RuntimeException) + { + return getSupportedServiceNames_static(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL ConsoleHandler::getImplementationName_static() + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.ConsoleHandler" ) ); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL ConsoleHandler::getSupportedServiceNames_static() + { + Sequence< ::rtl::OUString > aServiceNames(1); + aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.ConsoleHandler" ) ); + return aServiceNames; + } + + //-------------------------------------------------------------------- + Reference< XInterface > ConsoleHandler::Create( const Reference< XComponentContext >& _rxContext ) + { + return *( new ConsoleHandler( _rxContext ) ); + } + + //-------------------------------------------------------------------- + void createRegistryInfo_ConsoleHandler() + { + static OAutoRegistration< ConsoleHandler > aAutoRegistration; + } + +//........................................................................ +} // namespace logging +//........................................................................ diff --git a/extensions/source/logging/csvformatter.cxx b/extensions/source/logging/csvformatter.cxx new file mode 100644 index 000000000000..5e02e5f7cb69 --- /dev/null +++ b/extensions/source/logging/csvformatter.cxx @@ -0,0 +1,382 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * +************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#include "log_module.hxx" + +#include <stdio.h> +#include <string> + +/** === begin UNO includes === **/ +#ifndef _COM_SUN_STAR_LOGGING_XLOGFORMATTER_HPP_ +#include <com/sun/star/logging/XCsvLogFormatter.hpp> +#endif +#ifndef _COM_SUN_STAR_LOGGING_XLOGFORMATTER_HPP_ +#include <com/sun/star/logging/XLogFormatter.hpp> +#endif +#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_ +#include <com/sun/star/uno/XComponentContext.hpp> +#endif +#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_ +#include <com/sun/star/lang/XServiceInfo.hpp> +#endif +/** === end UNO includes === **/ + +#include <comphelper/componentcontext.hxx> + +#include <cppuhelper/implbase2.hxx> + +#include <rtl/ustrbuf.hxx> + +#include <osl/thread.h> + +namespace logging +{ + + /** === begin UNO using === **/ + using ::com::sun::star::logging::XCsvLogFormatter; + using ::com::sun::star::logging::XLogFormatter; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::lang::XServiceInfo; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::logging::LogRecord; + using ::com::sun::star::uno::XInterface; + /** === end UNO using === **/ + + //= CsvFormatter - declaration + //= formats for csv files as defined by RFC4180 + typedef ::cppu::WeakImplHelper2 < XCsvLogFormatter + , XServiceInfo + > CsvFormatter_Base; + class CsvFormatter : public CsvFormatter_Base + { + public: + virtual ::rtl::OUString SAL_CALL formatMultiColumn(const Sequence< ::rtl::OUString>& column_data) throw (RuntimeException); + + // XServiceInfo - static version + static ::rtl::OUString SAL_CALL getImplementationName_static(); + static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + static Reference< XInterface > Create( const Reference< XComponentContext >& context ); + + protected: + CsvFormatter( const Reference< XComponentContext >& context ); + virtual ~CsvFormatter(); + + // XCsvLogFormatter + virtual ::sal_Bool SAL_CALL getLogEventNo() throw (RuntimeException); + virtual ::sal_Bool SAL_CALL getLogThread() throw (RuntimeException); + virtual ::sal_Bool SAL_CALL getLogTimestamp() throw (RuntimeException); + virtual ::sal_Bool SAL_CALL getLogSource() throw (RuntimeException); + virtual Sequence< ::rtl::OUString > SAL_CALL getColumnnames() throw (RuntimeException); + + virtual void SAL_CALL setLogEventNo( ::sal_Bool log_event_no ) throw (RuntimeException); + virtual void SAL_CALL setLogThread( ::sal_Bool log_thread ) throw (RuntimeException); + virtual void SAL_CALL setLogTimestamp( ::sal_Bool log_timestamp ) throw (RuntimeException); + virtual void SAL_CALL setLogSource( ::sal_Bool log_source ) throw (RuntimeException); + virtual void SAL_CALL setColumnnames( const Sequence< ::rtl::OUString>& column_names) throw (RuntimeException); + + // XLogFormatter + virtual ::rtl::OUString SAL_CALL getHead( ) throw (RuntimeException); + virtual ::rtl::OUString SAL_CALL format( const LogRecord& Record ) throw (RuntimeException); + virtual ::rtl::OUString SAL_CALL getTail( ) throw (RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& service_name ) throw(RuntimeException); + virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); + + private: + ::comphelper::ComponentContext m_aContext; + ::sal_Bool m_LogEventNo; + ::sal_Bool m_LogThread; + ::sal_Bool m_LogTimestamp; + ::sal_Bool m_LogSource; + ::sal_Bool m_MultiColumn; + ::com::sun::star::uno::Sequence< ::rtl::OUString > m_Columnnames; + }; +} // namespace logging + +//= private helpers +namespace +{ + const sal_Unicode quote_char = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"")).toChar(); + const sal_Unicode comma_char = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(",")).toChar(); + const ::rtl::OUString dos_newline = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\r\n")); + + inline bool needsQuoting(const ::rtl::OUString& str) + { + static const ::rtl::OUString quote_trigger_chars = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("\",\n\r")); + sal_Int32 len = str.getLength(); + for(sal_Int32 i=0; i<len; i++) + if(quote_trigger_chars.indexOf(str[i])!=-1) + return true; + return false; + }; + + inline void appendEncodedString(::rtl::OUStringBuffer& buf, const ::rtl::OUString& str) + { + if(needsQuoting(str)) + { + // each double-quote will get replaced by two double-quotes + buf.append(quote_char); + const sal_Int32 buf_offset = buf.getLength(); + const sal_Int32 str_length = str.getLength(); + buf.append(str); + // special treatment for the last character + if(quote_char==str[str_length-1]) + buf.append(quote_char); + // iterating backwards because the index at which we insert wont be shifted + // when moving that way. + for(sal_Int32 i = str_length; i>=0; ) + { + i=str.lastIndexOf(quote_char, --i); + if(i!=-1) + buf.insert(buf_offset + i, quote_char); + } + buf.append(quote_char); + } + else + buf.append(str); + }; + + ::com::sun::star::uno::Sequence< ::rtl::OUString> initialColumns() + { + com::sun::star::uno::Sequence< ::rtl::OUString> result = ::com::sun::star::uno::Sequence< ::rtl::OUString>(1); + result[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("message")); + return result; + }; +} + +//= CsvFormatter - implementation +namespace logging +{ + CsvFormatter::CsvFormatter( const Reference< XComponentContext >& context ) + :m_aContext( context ), + m_LogEventNo(true), + m_LogThread(true), + m_LogTimestamp(true), + m_LogSource(false), + m_MultiColumn(false), + m_Columnnames(initialColumns()) + { } + + CsvFormatter::~CsvFormatter() + { } + + ::sal_Bool CsvFormatter::getLogEventNo() throw (RuntimeException) + { + return m_LogEventNo; + } + + ::sal_Bool CsvFormatter::getLogThread() throw (RuntimeException) + { + return m_LogThread; + } + + ::sal_Bool CsvFormatter::getLogTimestamp() throw (RuntimeException) + { + return m_LogTimestamp; + } + + ::sal_Bool CsvFormatter::getLogSource() throw (RuntimeException) + { + return m_LogSource; + } + + Sequence< ::rtl::OUString > CsvFormatter::getColumnnames() throw (RuntimeException) + { + return m_Columnnames; + } + + void CsvFormatter::setLogEventNo(::sal_Bool log_event_no) throw (RuntimeException) + { + m_LogEventNo = log_event_no; + } + + void CsvFormatter::setLogThread(::sal_Bool log_thread) throw (RuntimeException) + { + m_LogThread = log_thread; + } + + void CsvFormatter::setLogTimestamp(::sal_Bool log_timestamp) throw (RuntimeException) + { + m_LogTimestamp = log_timestamp; + } + + void CsvFormatter::setLogSource(::sal_Bool log_source) throw (RuntimeException) + { + m_LogSource = log_source; + } + + void CsvFormatter::setColumnnames(const Sequence< ::rtl::OUString >& columnnames) throw (RuntimeException) + { + m_Columnnames = Sequence< ::rtl::OUString>(columnnames); + m_MultiColumn = (m_Columnnames.getLength()>1); + } + + ::rtl::OUString SAL_CALL CsvFormatter::getHead( ) throw (RuntimeException) + { + ::rtl::OUStringBuffer buf; + if(m_LogEventNo) + buf.appendAscii("event no,"); + if(m_LogThread) + buf.appendAscii("thread,"); + if(m_LogTimestamp) + buf.appendAscii("timestamp,"); + if(m_LogSource) + buf.appendAscii("class,method,"); + sal_Int32 columns = m_Columnnames.getLength(); + for(sal_Int32 i=0; i<columns; i++) + { + buf.append(m_Columnnames[i]); + buf.append(comma_char); + } + buf.setLength(buf.getLength()-1); + buf.append(dos_newline); + return buf.makeStringAndClear(); + } + + ::rtl::OUString SAL_CALL CsvFormatter::format( const LogRecord& record ) throw (RuntimeException) + { + ::rtl::OUStringBuffer aLogEntry; + + if(m_LogEventNo) + { + aLogEntry.append( record.SequenceNumber ); + aLogEntry.append(comma_char); + } + + if(m_LogThread) + { + aLogEntry.append( record.ThreadID ); + aLogEntry.append(comma_char); + } + + if(m_LogTimestamp) + { + // ISO 8601 + char buffer[ 30 ]; + const size_t buffer_size = sizeof( buffer ); + snprintf( buffer, buffer_size, "%04i-%02i-%02iT%02i:%02i:%02i.%02i", + (int)record.LogTime.Year, + (int)record.LogTime.Month, + (int)record.LogTime.Day, + (int)record.LogTime.Hours, + (int)record.LogTime.Minutes, + (int)record.LogTime.Seconds, + (int)record.LogTime.HundredthSeconds ); + aLogEntry.appendAscii( buffer ); + aLogEntry.append(comma_char); + } + + if(m_LogSource) + { + appendEncodedString(aLogEntry, record.SourceClassName); + aLogEntry.append(comma_char); + + appendEncodedString(aLogEntry, record.SourceMethodName); + aLogEntry.append(comma_char); + } + + // if the CsvFormatter has multiple columns set via setColumnnames(), the + // message of the record is expected to be encoded with formatMultiColumn + // if the CsvFormatter has only one column set, the message is expected not + // to be encoded + if(m_MultiColumn) + aLogEntry.append(record.Message); + else + appendEncodedString(aLogEntry, record.Message); + + aLogEntry.append( dos_newline ); + return aLogEntry.makeStringAndClear(); + } + + ::rtl::OUString SAL_CALL CsvFormatter::getTail( ) throw (RuntimeException) + { + return ::rtl::OUString(); + } + + ::rtl::OUString SAL_CALL CsvFormatter::formatMultiColumn(const Sequence< ::rtl::OUString>& column_data) throw (RuntimeException) + { + sal_Int32 columns = column_data.getLength(); + ::rtl::OUStringBuffer buf; + for(int i=0; i<columns; i++) + { + appendEncodedString(buf, column_data[i]); + buf.append(comma_char); + } + buf.setLength(buf.getLength()-1); + return buf.makeStringAndClear(); + } + + ::sal_Bool SAL_CALL CsvFormatter::supportsService( const ::rtl::OUString& service_name ) throw(RuntimeException) + { + const Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames() ); + for ( const ::rtl::OUString* pServiceNames = aServiceNames.getConstArray(); + pServiceNames != aServiceNames.getConstArray() + aServiceNames.getLength(); + ++pServiceNames + ) + if ( service_name == *pServiceNames ) + return sal_True; + return sal_False; + } + + ::rtl::OUString SAL_CALL CsvFormatter::getImplementationName() throw(RuntimeException) + { + return getImplementationName_static(); + } + + Sequence< ::rtl::OUString > SAL_CALL CsvFormatter::getSupportedServiceNames() throw(RuntimeException) + { + return getSupportedServiceNames_static(); + } + + ::rtl::OUString SAL_CALL CsvFormatter::getImplementationName_static() + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.CsvFormatter" ) ); + } + + Sequence< ::rtl::OUString > SAL_CALL CsvFormatter::getSupportedServiceNames_static() + { + Sequence< ::rtl::OUString > aServiceNames(1); + aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.CsvFormatter" ) ); + return aServiceNames; + } + + Reference< XInterface > CsvFormatter::Create( const Reference< XComponentContext >& context ) + { + return *( new CsvFormatter( context ) ); + } + + void createRegistryInfo_CsvFormatter() + { + static OAutoRegistration< CsvFormatter > aAutoRegistration; + } +} // namespace logging diff --git a/extensions/source/logging/filehandler.cxx b/extensions/source/logging/filehandler.cxx new file mode 100644 index 000000000000..be233898c2ab --- /dev/null +++ b/extensions/source/logging/filehandler.cxx @@ -0,0 +1,441 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#include "log_module.hxx" +#include "methodguard.hxx" +#include "loghandler.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/logging/XLogHandler.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/ucb/AlreadyInitializedException.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/util/XStringSubstitution.hpp> +/** === end UNO includes === **/ + +#include <tools/diagnose_ex.h> + +#include <comphelper/componentcontext.hxx> + +#include <cppuhelper/compbase3.hxx> +#include <cppuhelper/basemutex.hxx> + +#include <osl/thread.h> +#include <osl/file.hxx> + +#include <rtl/strbuf.hxx> + +#include <memory> + +//........................................................................ +namespace logging +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::logging::LogRecord; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::logging::XLogFormatter; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::logging::XLogHandler; + using ::com::sun::star::lang::XServiceInfo; + using ::com::sun::star::ucb::AlreadyInitializedException; + using ::com::sun::star::lang::XInitialization; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::util::XStringSubstitution; + using ::com::sun::star::beans::NamedValue; + /** === end UNO using === **/ + + //==================================================================== + //= FileHandler - declaration + //==================================================================== + typedef ::cppu::WeakComponentImplHelper3 < XLogHandler + , XServiceInfo + , XInitialization + > FileHandler_Base; + class FileHandler :public ::cppu::BaseMutex + ,public FileHandler_Base + { + private: + enum FileValidity + { + /// never attempted to open the file + eUnknown, + /// file is valid + eValid, + /// file is invalid + eInvalid + }; + + private: + ::comphelper::ComponentContext m_aContext; + LogHandlerHelper m_aHandlerHelper; + ::rtl::OUString m_sFileURL; + ::std::auto_ptr< ::osl::File > m_pFile; + FileValidity m_eFileValidity; + + protected: + FileHandler( const Reference< XComponentContext >& _rxContext ); + virtual ~FileHandler(); + + // XLogHandler + virtual ::rtl::OUString SAL_CALL getEncoding() throw (RuntimeException); + virtual void SAL_CALL setEncoding( const ::rtl::OUString& _encoding ) throw (RuntimeException); + virtual Reference< XLogFormatter > SAL_CALL getFormatter() throw (RuntimeException); + virtual void SAL_CALL setFormatter( const Reference< XLogFormatter >& _formatter ) throw (RuntimeException); + virtual ::sal_Int32 SAL_CALL getLevel() throw (RuntimeException); + virtual void SAL_CALL setLevel( ::sal_Int32 _level ) throw (RuntimeException); + virtual void SAL_CALL flush( ) throw (RuntimeException); + virtual ::sal_Bool SAL_CALL publish( const LogRecord& Record ) throw (RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException); + virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); + + // OComponentHelper + virtual void SAL_CALL disposing(); + + public: + // XServiceInfo - static version + static ::rtl::OUString SAL_CALL getImplementationName_static(); + static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext ); + + public: + typedef ComponentMethodGuard< FileHandler > MethodGuard; + void enterMethod( MethodGuard::Access ); + void leaveMethod( MethodGuard::Access ); + + private: + /** prepares our output file for writing + */ + bool impl_prepareFile_nothrow(); + + /// writes the given string to our file + void impl_writeString_nothrow( const ::rtl::OString& _rEntry ); + + /** does string substitution on a (usually externally provided) file url + */ + void impl_doStringsubstitution_nothrow( ::rtl::OUString& _inout_rURL ); + }; + + //==================================================================== + //= FileHandler - implementation + //==================================================================== + //-------------------------------------------------------------------- + FileHandler::FileHandler( const Reference< XComponentContext >& _rxContext ) + :FileHandler_Base( m_aMutex ) + ,m_aContext( _rxContext ) + ,m_aHandlerHelper( _rxContext, m_aMutex, rBHelper ) + ,m_sFileURL( ) + ,m_pFile( ) + ,m_eFileValidity( eUnknown ) + { + } + + //-------------------------------------------------------------------- + FileHandler::~FileHandler() + { + if ( !rBHelper.bDisposed ) + { + acquire(); + dispose(); + } + } + + //-------------------------------------------------------------------- + bool FileHandler::impl_prepareFile_nothrow() + { + if ( m_eFileValidity == eUnknown ) + { + m_pFile.reset( new ::osl::File( m_sFileURL ) ); + // check whether the log file already exists + ::osl::DirectoryItem aFileItem; + ::osl::DirectoryItem::get( m_sFileURL, aFileItem ); + ::osl::FileStatus aStatus( FileStatusMask_Validate ); + if ( ::osl::FileBase::E_None == aFileItem.getFileStatus( aStatus ) ) + ::osl::File::remove( m_sFileURL ); + + ::osl::FileBase::RC res = m_pFile->open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ); + m_eFileValidity = res == ::osl::FileBase::E_None + ? eValid + : eInvalid; + #if OSL_DEBUG_LEVEL > 0 + if ( m_eFileValidity == eInvalid ) + { + ::rtl::OStringBuffer sMessage; + sMessage.append( "FileHandler::impl_prepareFile_nothrow: could not open the designated log file:" ); + sMessage.append( "\nURL: " ); + sMessage.append( ::rtl::OString( m_sFileURL.getStr(), m_sFileURL.getLength(), osl_getThreadTextEncoding() ) ); + sMessage.append( "\nerror code: " ); + sMessage.append( (sal_Int32)res ); + OSL_ENSURE( false, sMessage.makeStringAndClear() ); + } + #endif + if ( m_eFileValidity == eValid ) + { + ::rtl::OString sHead; + if ( m_aHandlerHelper.getEncodedHead( sHead ) ) + impl_writeString_nothrow( sHead ); + } + } + + return m_eFileValidity == eValid; + } + + //-------------------------------------------------------------------- + void FileHandler::impl_writeString_nothrow( const ::rtl::OString& _rEntry ) + { + OSL_PRECOND( m_pFile.get(), "FileHandler::impl_writeString_nothrow: no file!" ); + + sal_uInt64 nBytesToWrite( _rEntry.getLength() ); + sal_uInt64 nBytesWritten( 0 ); + #if OSL_DEBUG_LEVEL > 0 + ::osl::FileBase::RC res = + #endif + m_pFile->write( _rEntry.getStr(), nBytesToWrite, nBytesWritten ); + OSL_ENSURE( ( res == ::osl::FileBase::E_None ) && ( nBytesWritten == nBytesToWrite ), + "FileHandler::impl_writeString_nothrow: could not write the log entry!" ); + } + + //-------------------------------------------------------------------- + void FileHandler::impl_doStringsubstitution_nothrow( ::rtl::OUString& _inout_rURL ) + { + try + { + Reference< XStringSubstitution > xStringSubst; + if ( m_aContext.createComponent( "com.sun.star.util.PathSubstitution", xStringSubst ) ) + _inout_rURL = xStringSubst->substituteVariables( _inout_rURL, true ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::disposing() + { + if ( m_eFileValidity == eValid ) + { + ::rtl::OString sTail; + if ( m_aHandlerHelper.getEncodedTail( sTail ) ) + impl_writeString_nothrow( sTail ); + } + + m_pFile.reset( NULL ); + m_aHandlerHelper.setFormatter( NULL ); + } + + //-------------------------------------------------------------------- + void FileHandler::enterMethod( MethodGuard::Access ) + { + m_aHandlerHelper.enterMethod(); + } + + //-------------------------------------------------------------------- + void FileHandler::leaveMethod( MethodGuard::Access ) + { + m_aMutex.release(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL FileHandler::getEncoding() throw (RuntimeException) + { + MethodGuard aGuard( *this ); + ::rtl::OUString sEncoding; + OSL_VERIFY( m_aHandlerHelper.getEncoding( sEncoding ) ); + return sEncoding; + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::setEncoding( const ::rtl::OUString& _rEncoding ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + OSL_VERIFY( m_aHandlerHelper.setEncoding( _rEncoding ) ); + } + + //-------------------------------------------------------------------- + Reference< XLogFormatter > SAL_CALL FileHandler::getFormatter() throw (RuntimeException) + { + MethodGuard aGuard( *this ); + return m_aHandlerHelper.getFormatter(); + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::setFormatter( const Reference< XLogFormatter >& _rxFormatter ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + m_aHandlerHelper.setFormatter( _rxFormatter ); + } + + //-------------------------------------------------------------------- + ::sal_Int32 SAL_CALL FileHandler::getLevel() throw (RuntimeException) + { + MethodGuard aGuard( *this ); + return m_aHandlerHelper.getLevel(); + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::setLevel( ::sal_Int32 _nLevel ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + m_aHandlerHelper.setLevel( _nLevel ); + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::flush( ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + if(!m_pFile.get()) + { + OSL_PRECOND(false, "FileHandler::flush: no file!"); + return; + } + #if OSL_DEBUG_LEVEL > 0 + ::osl::FileBase::RC res = + #endif + m_pFile->sync(); + OSL_ENSURE(res == ::osl::FileBase::E_None, "FileHandler::flush: Could not sync logfile to filesystem."); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL FileHandler::publish( const LogRecord& _rRecord ) throw (RuntimeException) + { + MethodGuard aGuard( *this ); + + if ( !impl_prepareFile_nothrow() ) + return sal_False; + + ::rtl::OString sEntry; + if ( !m_aHandlerHelper.formatForPublishing( _rRecord, sEntry ) ) + return sal_False; + + impl_writeString_nothrow( sEntry ); + return sal_True; + } + + //-------------------------------------------------------------------- + void SAL_CALL FileHandler::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( m_aHandlerHelper.getIsInitialized() ) + throw AlreadyInitializedException(); + + if ( _rArguments.getLength() != 1 ) + throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); + + Sequence< NamedValue > aSettings; + if ( _rArguments[0] >>= m_sFileURL ) + { + // create( [in] string URL ); + impl_doStringsubstitution_nothrow( m_sFileURL ); + } + else if ( _rArguments[0] >>= aSettings ) + { + // createWithSettings( [in] sequence< ::com::sun::star::beans::NamedValue > Settings ) + ::comphelper::NamedValueCollection aTypedSettings( aSettings ); + m_aHandlerHelper.initFromSettings( aTypedSettings ); + + if ( aTypedSettings.get_ensureType( "FileURL", m_sFileURL ) ) + impl_doStringsubstitution_nothrow( m_sFileURL ); + } + else + throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); + + m_aHandlerHelper.setIsInitialized(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL FileHandler::getImplementationName() throw(RuntimeException) + { + return getImplementationName_static(); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL FileHandler::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException) + { + const Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames() ); + for ( const ::rtl::OUString* pServiceNames = aServiceNames.getConstArray(); + pServiceNames != aServiceNames.getConstArray() + aServiceNames.getLength(); + ++pServiceNames + ) + if ( _rServiceName == *pServiceNames ) + return sal_True; + return sal_False; + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL FileHandler::getSupportedServiceNames() throw(RuntimeException) + { + return getSupportedServiceNames_static(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL FileHandler::getImplementationName_static() + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.FileHandler" ) ); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL FileHandler::getSupportedServiceNames_static() + { + Sequence< ::rtl::OUString > aServiceNames(1); + aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.FileHandler" ) ); + return aServiceNames; + } + + //-------------------------------------------------------------------- + Reference< XInterface > FileHandler::Create( const Reference< XComponentContext >& _rxContext ) + { + return *( new FileHandler( _rxContext ) ); + } + + //-------------------------------------------------------------------- + void createRegistryInfo_FileHandler() + { + static OAutoRegistration< FileHandler > aAutoRegistration; + } + +//........................................................................ +} // namespace logging +//........................................................................ diff --git a/extensions/source/logging/log.component b/extensions/source/logging/log.component new file mode 100644 index 000000000000..4dd2db56c3cc --- /dev/null +++ b/extensions/source/logging/log.component @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* This file is part of OpenOffice.org. +* +* OpenOffice.org is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License version 3 +* only, as published by the Free Software Foundation. +* +* OpenOffice.org is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License version 3 for more details +* (a copy is included in the LICENSE file that accompanied this code). +* +* You should have received a copy of the GNU Lesser General Public License +* version 3 along with OpenOffice.org. If not, see +* <http://www.openoffice.org/license.html> +* for a copy of the LGPLv3 License. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.comp.extensions.ConsoleHandler"> + <service name="com.sun.star.logging.ConsoleHandler"/> + </implementation> + <implementation name="com.sun.star.comp.extensions.CsvFormatter"> + <service name="com.sun.star.logging.CsvFormatter"/> + </implementation> + <implementation name="com.sun.star.comp.extensions.FileHandler"> + <service name="com.sun.star.logging.FileHandler"/> + </implementation> + <implementation name="com.sun.star.comp.extensions.LoggerPool"> + <service name="com.sun.star.logging.LoggerPool"/> + <singleton name="com.sun.star.logging.LoggerPool"/> + </implementation> + <implementation name="com.sun.star.comp.extensions.PlainTextFormatter"> + <service name="com.sun.star.logging.PlainTextFormatter"/> + </implementation> +</component> diff --git a/extensions/source/logging/log_module.cxx b/extensions/source/logging/log_module.cxx new file mode 100644 index 000000000000..dc5f52d8df3f --- /dev/null +++ b/extensions/source/logging/log_module.cxx @@ -0,0 +1,43 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" +#include "log_module.hxx" +#include <rtl/instance.hxx> + +//........................................................................ +namespace logging +{ +//........................................................................ + + IMPLEMENT_COMPONENT_MODULE( LogModule ); + +//........................................................................ +} // namespace logging +//........................................................................ + diff --git a/extensions/source/logging/log_module.hxx b/extensions/source/logging/log_module.hxx new file mode 100644 index 000000000000..fcb5732937df --- /dev/null +++ b/extensions/source/logging/log_module.hxx @@ -0,0 +1,45 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef EXTENSIONS_LOG_MODULE_HXX +#define EXTENSIONS_LOG_MODULE_HXX + +#include <comphelper/componentmodule.hxx> + +//........................................................................ +namespace logging +{ +//........................................................................ + + DECLARE_COMPONENT_MODULE( LogModule, LogModuleClient ) + +//........................................................................ +} // namespace logging +//........................................................................ + +#endif // EXTENSIONS_LOG_MODULE_HXX + diff --git a/extensions/source/logging/log_services.cxx b/extensions/source/logging/log_services.cxx new file mode 100644 index 000000000000..421302a5a54b --- /dev/null +++ b/extensions/source/logging/log_services.cxx @@ -0,0 +1,69 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ +#include "log_module.hxx" + +//........................................................................ +namespace logging +{ +//........................................................................ + + //-------------------------------------------------------------------- + extern void createRegistryInfo_LoggerPool(); + extern void createRegistryInfo_FileHandler(); + extern void createRegistryInfo_ConsoleHandler(); + extern void createRegistryInfo_PlainTextFormatter(); + extern void createRegistryInfo_CsvFormatter(); + + static void initializeModule() + { + static bool bInitialized( false ); + if ( !bInitialized ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !bInitialized ) + { + createRegistryInfo_LoggerPool(); + createRegistryInfo_FileHandler(); + createRegistryInfo_ConsoleHandler(); + createRegistryInfo_PlainTextFormatter(); + createRegistryInfo_CsvFormatter(); + } + } + } + +//........................................................................ +} // namespace logging +//........................................................................ + +IMPLEMENT_COMPONENT_LIBRARY_API( ::logging::LogModule, ::logging::initializeModule ) + diff --git a/extensions/source/logging/logger.cxx b/extensions/source/logging/logger.cxx new file mode 100644 index 000000000000..747225937356 --- /dev/null +++ b/extensions/source/logging/logger.cxx @@ -0,0 +1,404 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#include "log_module.hxx" +#include "logrecord.hxx" +#include "loggerconfig.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/logging/XLogger.hpp> +#include <com/sun/star/logging/LogLevel.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/logging/XLoggerPool.hpp> +/** === end UNO includes === **/ + +#include <tools/diagnose_ex.h> + +#include <comphelper/componentcontext.hxx> + +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/weakref.hxx> + +#include <boost/bind.hpp> + +#include <map> + +//........................................................................ +namespace logging +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::logging::XLogger; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::lang::XServiceInfo; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::WeakReference; + using ::com::sun::star::logging::XLogHandler; + using ::com::sun::star::logging::XLoggerPool; + using ::com::sun::star::logging::LogRecord; + /** === end UNO using === **/ + namespace LogLevel = ::com::sun::star::logging::LogLevel; + + //==================================================================== + //= helper + //==================================================================== + namespace + { + sal_Bool lcl_supportsService_nothrow( XServiceInfo& _rSI, const ::rtl::OUString& _rServiceName ) + { + const Sequence< ::rtl::OUString > aServiceNames( _rSI.getSupportedServiceNames() ); + for ( const ::rtl::OUString* pServiceNames = aServiceNames.getConstArray(); + pServiceNames != aServiceNames.getConstArray() + aServiceNames.getLength(); + ++pServiceNames + ) + if ( _rServiceName == *pServiceNames ) + return sal_True; + return sal_False; + } + } + + //==================================================================== + //= EventLogger - declaration + //==================================================================== + typedef ::cppu::WeakImplHelper2 < XLogger + , XServiceInfo + > EventLogger_Base; + class EventLogger :public ::cppu::BaseMutex + ,public EventLogger_Base + { + private: + ::comphelper::ComponentContext m_aContext; + ::cppu::OInterfaceContainerHelper m_aHandlers; + oslInterlockedCount m_nEventNumber; + + // <attributes> + sal_Int32 m_nLogLevel; + ::rtl::OUString m_sName; + // </attributes> + + public: + EventLogger( const Reference< XComponentContext >& _rxContext, const ::rtl::OUString& _rName ); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException); + virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); + + // XLogger + virtual ::rtl::OUString SAL_CALL getName() throw (RuntimeException); + virtual ::sal_Int32 SAL_CALL getLevel() throw (RuntimeException); + virtual void SAL_CALL setLevel( ::sal_Int32 _level ) throw (RuntimeException); + virtual void SAL_CALL addLogHandler( const Reference< XLogHandler >& LogHandler ) throw (RuntimeException); + virtual void SAL_CALL removeLogHandler( const Reference< XLogHandler >& LogHandler ) throw (RuntimeException); + virtual ::sal_Bool SAL_CALL isLoggable( ::sal_Int32 _nLevel ) throw (RuntimeException); + virtual void SAL_CALL log( ::sal_Int32 Level, const ::rtl::OUString& Message ) throw (RuntimeException); + virtual void SAL_CALL logp( ::sal_Int32 Level, const ::rtl::OUString& SourceClass, const ::rtl::OUString& SourceMethod, const ::rtl::OUString& Message ) throw (RuntimeException); + + protected: + ~EventLogger(); + + private: + /** logs the given log record + */ + void impl_ts_logEvent_nothrow( const LogRecord& _rRecord ); + + /** non-threadsafe impl-version of isLoggable + */ + bool impl_nts_isLoggable_nothrow( ::sal_Int32 _nLevel ); + }; + + //==================================================================== + //= LoggerPool - declaration + //==================================================================== + typedef ::cppu::WeakImplHelper2 < XLoggerPool + , XServiceInfo + > LoggerPool_Base; + /** administrates a pool of XLogger instances, where a logger is keyed by its name, + and subsequent requests for a logger with the same name return the same instance. + */ + class LoggerPool : public LoggerPool_Base + { + private: + typedef ::std::map< ::rtl::OUString, WeakReference< XLogger > > ImplPool; + + private: + ::osl::Mutex m_aMutex; + ::comphelper::ComponentContext m_aContext; + ImplPool m_aImpl; + + public: + LoggerPool( const Reference< XComponentContext >& _rxContext ); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException); + virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); + + // helper for factories + static Sequence< ::rtl::OUString > getSupportedServiceNames_static(); + static ::rtl::OUString getImplementationName_static(); + static ::rtl::OUString getSingletonName_static(); + static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext ); + + // XLoggerPool + virtual Reference< XLogger > SAL_CALL getNamedLogger( const ::rtl::OUString& Name ) throw (RuntimeException); + virtual Reference< XLogger > SAL_CALL getDefaultLogger( ) throw (RuntimeException); + }; + + //==================================================================== + //= EventLogger - implementation + //==================================================================== + //-------------------------------------------------------------------- + EventLogger::EventLogger( const Reference< XComponentContext >& _rxContext, const ::rtl::OUString& _rName ) + :m_aContext( _rxContext ) + ,m_aHandlers( m_aMutex ) + ,m_nEventNumber( 0 ) + ,m_nLogLevel( LogLevel::OFF ) + ,m_sName( _rName ) + { + osl_incrementInterlockedCount( &m_refCount ); + { + initializeLoggerFromConfiguration( m_aContext, this ); + } + osl_decrementInterlockedCount( &m_refCount ); + } + + //-------------------------------------------------------------------- + EventLogger::~EventLogger() + { + } + + //-------------------------------------------------------------------- + bool EventLogger::impl_nts_isLoggable_nothrow( ::sal_Int32 _nLevel ) + { + if ( _nLevel < m_nLogLevel ) + return false; + + if ( !m_aHandlers.getLength() ) + return false; + + return true; + } + + //-------------------------------------------------------------------- + void EventLogger::impl_ts_logEvent_nothrow( const LogRecord& _rRecord ) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + if ( !impl_nts_isLoggable_nothrow( _rRecord.Level ) ) + return; + + m_aHandlers.forEach< XLogHandler >( + ::boost::bind( &XLogHandler::publish, _1, ::boost::cref( _rRecord ) ) ); + m_aHandlers.forEach< XLogHandler >( + ::boost::bind( &XLogHandler::flush, _1 ) ); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL EventLogger::getName() throw (RuntimeException) + { + return m_sName; + } + + //-------------------------------------------------------------------- + ::sal_Int32 SAL_CALL EventLogger::getLevel() throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + return m_nLogLevel; + } + + //-------------------------------------------------------------------- + void SAL_CALL EventLogger::setLevel( ::sal_Int32 _level ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + m_nLogLevel = _level; + } + + //-------------------------------------------------------------------- + void SAL_CALL EventLogger::addLogHandler( const Reference< XLogHandler >& _rxLogHandler ) throw (RuntimeException) + { + if ( _rxLogHandler.is() ) + m_aHandlers.addInterface( _rxLogHandler ); + } + + //-------------------------------------------------------------------- + void SAL_CALL EventLogger::removeLogHandler( const Reference< XLogHandler >& _rxLogHandler ) throw (RuntimeException) + { + if ( _rxLogHandler.is() ) + m_aHandlers.removeInterface( _rxLogHandler ); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL EventLogger::isLoggable( ::sal_Int32 _nLevel ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + return impl_nts_isLoggable_nothrow( _nLevel ); + } + + //-------------------------------------------------------------------- + void SAL_CALL EventLogger::log( ::sal_Int32 _nLevel, const ::rtl::OUString& _rMessage ) throw (RuntimeException) + { + impl_ts_logEvent_nothrow( createLogRecord( + m_sName, + _rMessage, + _nLevel, + osl_incrementInterlockedCount( &m_nEventNumber ) + ) ); + } + + //-------------------------------------------------------------------- + void SAL_CALL EventLogger::logp( ::sal_Int32 _nLevel, const ::rtl::OUString& _rSourceClass, const ::rtl::OUString& _rSourceMethod, const ::rtl::OUString& _rMessage ) throw (RuntimeException) + { + impl_ts_logEvent_nothrow( createLogRecord( + m_sName, + _rSourceClass, + _rSourceMethod, + _rMessage, + _nLevel, + osl_incrementInterlockedCount( &m_nEventNumber ) + ) ); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL EventLogger::getImplementationName() throw(RuntimeException) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.EventLogger" ) ); + } + + //-------------------------------------------------------------------- + ::sal_Bool EventLogger::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException) + { + return lcl_supportsService_nothrow( *this, _rServiceName ); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL EventLogger::getSupportedServiceNames() throw(RuntimeException) + { + Sequence< ::rtl::OUString > aServiceNames(1); + aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.Logger" ) ); + return aServiceNames; + } + + //==================================================================== + //= LoggerPool - implementation + //==================================================================== + //-------------------------------------------------------------------- + LoggerPool::LoggerPool( const Reference< XComponentContext >& _rxContext ) + :m_aContext( _rxContext ) + { + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL LoggerPool::getImplementationName() throw(RuntimeException) + { + return getImplementationName_static(); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL LoggerPool::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException) + { + return lcl_supportsService_nothrow( *this, _rServiceName ); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL LoggerPool::getSupportedServiceNames() throw(RuntimeException) + { + return getSupportedServiceNames_static(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL LoggerPool::getImplementationName_static() + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.LoggerPool" ) ); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL LoggerPool::getSupportedServiceNames_static() + { + Sequence< ::rtl::OUString > aServiceNames(1); + aServiceNames[0] = getSingletonName_static(); + return aServiceNames; + } + + //-------------------------------------------------------------------- + ::rtl::OUString LoggerPool::getSingletonName_static() + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.LoggerPool" ) ); + } + + //-------------------------------------------------------------------- + Reference< XInterface > SAL_CALL LoggerPool::Create( const Reference< XComponentContext >& _rxContext ) + { + return *( new LoggerPool( _rxContext ) ); + } + + //-------------------------------------------------------------------- + Reference< XLogger > SAL_CALL LoggerPool::getNamedLogger( const ::rtl::OUString& _rName ) throw (RuntimeException) + { + ::osl::MutexGuard aGuard( m_aMutex ); + + WeakReference< XLogger >& rLogger( m_aImpl[ _rName ] ); + Reference< XLogger > xLogger( (Reference< XLogger >)rLogger ); + if ( !xLogger.is() ) + { + // never requested before, or already dead + xLogger = new EventLogger( m_aContext.getUNOContext(), _rName ); + rLogger = xLogger; + } + + return xLogger; + } + + //-------------------------------------------------------------------- + Reference< XLogger > SAL_CALL LoggerPool::getDefaultLogger( ) throw (RuntimeException) + { + return getNamedLogger( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.logging.DefaultLogger" ) ) ); + } + + //-------------------------------------------------------------------- + void createRegistryInfo_LoggerPool() + { + static OSingletonRegistration< LoggerPool > aAutoRegistration; + } + +//........................................................................ +} // namespace logging +//........................................................................ + diff --git a/extensions/source/logging/loggerconfig.cxx b/extensions/source/logging/loggerconfig.cxx new file mode 100644 index 000000000000..949d236d6b67 --- /dev/null +++ b/extensions/source/logging/loggerconfig.cxx @@ -0,0 +1,283 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#include "loggerconfig.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/util/XChangesBatch.hpp> +#include <com/sun/star/logging/LogLevel.hpp> +#include <com/sun/star/lang/NullPointerException.hpp> +#include <com/sun/star/lang/ServiceNotRegisteredException.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/logging/XLogHandler.hpp> +#include <com/sun/star/logging/XLogFormatter.hpp> +/** === end UNO includes === **/ + +#include <tools/diagnose_ex.h> + +#include <comphelper/componentcontext.hxx> + +#include <cppuhelper/component_context.hxx> + +#include <vector> + +//........................................................................ +namespace logging +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::logging::XLogger; + using ::com::sun::star::lang::XMultiServiceFactory; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Any; + using ::com::sun::star::container::XNameContainer; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::lang::XSingleServiceFactory; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::util::XChangesBatch; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::lang::NullPointerException; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::lang::ServiceNotRegisteredException; + using ::com::sun::star::beans::NamedValue; + using ::com::sun::star::logging::XLogHandler; + using ::com::sun::star::logging::XLogFormatter; + using ::com::sun::star::container::XNameAccess; + using ::com::sun::star::uno::XComponentContext; + /** === end UNO using === **/ + namespace LogLevel = ::com::sun::star::logging::LogLevel; + + namespace + { + //---------------------------------------------------------------- + typedef void (*SettingTranslation)( const Reference< XLogger >&, const ::rtl::OUString&, Any& ); + + //---------------------------------------------------------------- + void lcl_substituteFileHandlerURLVariables_nothrow( const Reference< XLogger >& _rxLogger, ::rtl::OUString& _inout_rFileURL ) + { + struct Variable + { + const sal_Char* pVariablePattern; + const sal_Int32 nPatternLength; + rtl_TextEncoding eEncoding; + const ::rtl::OUString sVariableValue; + + Variable( const sal_Char* _pVariablePattern, const sal_Int32 _nPatternLength, rtl_TextEncoding _eEncoding, + const ::rtl::OUString& _rVariableValue ) + :pVariablePattern( _pVariablePattern ) + ,nPatternLength( _nPatternLength ) + ,eEncoding( _eEncoding ) + ,sVariableValue( _rVariableValue ) + { + } + }; + + ::rtl::OUString sLoggerName; + try { sLoggerName = _rxLogger->getName(); } + catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } + + Variable aVariables[] = + { + Variable( RTL_CONSTASCII_USTRINGPARAM( "$(loggername)" ), sLoggerName ) + }; + + for ( size_t i = 0; i < sizeof( aVariables ) / sizeof( aVariables[0] ); ++i ) + { + ::rtl::OUString sPattern( aVariables[i].pVariablePattern, aVariables[i].nPatternLength, aVariables[i].eEncoding ); + sal_Int32 nVariableIndex = _inout_rFileURL.indexOf( sPattern ); + if ( ( nVariableIndex == 0 ) + || ( ( nVariableIndex > 0 ) + && ( sPattern[ nVariableIndex - 1 ] != '$' ) + ) + ) + { + // found an (unescaped) variable + _inout_rFileURL = _inout_rFileURL.replaceAt( nVariableIndex, sPattern.getLength(), aVariables[i].sVariableValue ); + } + } + } + + //---------------------------------------------------------------- + void lcl_transformFileHandlerSettings_nothrow( const Reference< XLogger >& _rxLogger, const ::rtl::OUString& _rSettingName, Any& _inout_rSettingValue ) + { + if ( !_rSettingName.equalsAscii( "FileURL" ) ) + // not interested in this setting + return; + + ::rtl::OUString sURL; + OSL_VERIFY( _inout_rSettingValue >>= sURL ); + lcl_substituteFileHandlerURLVariables_nothrow( _rxLogger, sURL ); + _inout_rSettingValue <<= sURL; + } + + //---------------------------------------------------------------- + Reference< XInterface > lcl_createInstanceFromSetting_throw( + const ::comphelper::ComponentContext& _rContext, + const Reference< XLogger >& _rxLogger, + const Reference< XNameAccess >& _rxLoggerSettings, + const sal_Char* _pServiceNameAsciiNodeName, + const sal_Char* _pServiceSettingsAsciiNodeName, + SettingTranslation _pSettingTranslation = NULL + ) + { + Reference< XInterface > xInstance; + + // read the settings for the to-be-created service + Reference< XNameAccess > xServiceSettingsNode( _rxLoggerSettings->getByName( + ::rtl::OUString::createFromAscii( _pServiceSettingsAsciiNodeName ) ), UNO_QUERY_THROW ); + + Sequence< ::rtl::OUString > aSettingNames( xServiceSettingsNode->getElementNames() ); + size_t nServiceSettingCount( aSettingNames.getLength() ); + Sequence< NamedValue > aSettings( nServiceSettingCount ); + if ( nServiceSettingCount ) + { + const ::rtl::OUString* pSettingNames = aSettingNames.getConstArray(); + const ::rtl::OUString* pSettingNamesEnd = aSettingNames.getConstArray() + aSettingNames.getLength(); + NamedValue* pSetting = aSettings.getArray(); + + for ( ; + pSettingNames != pSettingNamesEnd; + ++pSettingNames, ++pSetting + ) + { + pSetting->Name = *pSettingNames; + pSetting->Value = xServiceSettingsNode->getByName( *pSettingNames ); + + if ( _pSettingTranslation ) + (_pSettingTranslation)( _rxLogger, pSetting->Name, pSetting->Value ); + } + } + + ::rtl::OUString sServiceName; + _rxLoggerSettings->getByName( ::rtl::OUString::createFromAscii( _pServiceNameAsciiNodeName ) ) >>= sServiceName; + if ( sServiceName.getLength() ) + { + bool bSuccess = false; + if ( aSettings.getLength() ) + { + Sequence< Any > aConstructionArgs(1); + aConstructionArgs[0] <<= aSettings; + bSuccess = _rContext.createComponentWithArguments( sServiceName, aConstructionArgs, xInstance ); + } + else + { + bSuccess = _rContext.createComponent( sServiceName, xInstance ); + } + + if ( !bSuccess ) + throw ServiceNotRegisteredException( sServiceName, NULL ); + } + + return xInstance; + } + } + + //-------------------------------------------------------------------- + void initializeLoggerFromConfiguration( const ::comphelper::ComponentContext& _rContext, const Reference< XLogger >& _rxLogger ) + { + try + { + if ( !_rxLogger.is() ) + throw NullPointerException(); + + // the configuration provider + Reference< XMultiServiceFactory > xConfigProvider; + ::rtl::OUString sConfigProvServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) ); + if ( !_rContext.createComponent( sConfigProvServiceName, xConfigProvider ) ) + throw ServiceNotRegisteredException( sConfigProvServiceName, _rxLogger ); + + // write access to the "Settings" node (which includes settings for all loggers) + Sequence< Any > aArguments(1); + aArguments[0] <<= NamedValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ), + makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Logging/Settings" ) ) ) + ); + Reference< XNameContainer > xAllSettings( xConfigProvider->createInstanceWithArguments( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) ), + aArguments + ), UNO_QUERY_THROW ); + + ::rtl::OUString sLoggerName( _rxLogger->getName() ); + if ( !xAllSettings->hasByName( sLoggerName ) ) + { + // no node yet for this logger. Create default settings. + Reference< XSingleServiceFactory > xNodeFactory( xAllSettings, UNO_QUERY_THROW ); + Reference< XInterface > xLoggerSettings( xNodeFactory->createInstance(), UNO_QUERY_THROW ); + xAllSettings->insertByName( sLoggerName, makeAny( xLoggerSettings ) ); + Reference< XChangesBatch > xChanges( xAllSettings, UNO_QUERY_THROW ); + xChanges->commitChanges(); + } + + // actually read and forward the settings + Reference< XNameAccess > xLoggerSettings( xAllSettings->getByName( sLoggerName ), UNO_QUERY_THROW ); + + // the log level + sal_Int32 nLogLevel( LogLevel::OFF ); + OSL_VERIFY( xLoggerSettings->getByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LogLevel" ) ) ) >>= nLogLevel ); + _rxLogger->setLevel( nLogLevel ); + + // the default handler, if any + Reference< XInterface > xUntyped( lcl_createInstanceFromSetting_throw( _rContext, _rxLogger, xLoggerSettings, "DefaultHandler", "HandlerSettings", &lcl_transformFileHandlerSettings_nothrow ) ); + if ( !xUntyped.is() ) + // no handler -> we're done + return; + Reference< XLogHandler > xHandler( xUntyped, UNO_QUERY_THROW ); + _rxLogger->addLogHandler( xHandler ); + + // The newly created handler might have an own (default) level. Ensure that it uses + // the same level as the logger. + xHandler->setLevel( nLogLevel ); + + // the default formatter for the handler + xUntyped = lcl_createInstanceFromSetting_throw( _rContext, _rxLogger, xLoggerSettings, "DefaultFormatter", "FormatterSettings" ); + if ( !xUntyped.is() ) + // no formatter -> we're done + return; + Reference< XLogFormatter > xFormatter( xUntyped, UNO_QUERY_THROW ); + xHandler->setFormatter( xFormatter ); + + // TODO: we could first create the formatter, then the handler. This would allow + // passing the formatter as value in the component context, so the handler would + // not create an own default formatter + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + +//........................................................................ +} // namespace logging +//........................................................................ diff --git a/extensions/source/logging/loggerconfig.hxx b/extensions/source/logging/loggerconfig.hxx new file mode 100644 index 000000000000..1d35cd13d84c --- /dev/null +++ b/extensions/source/logging/loggerconfig.hxx @@ -0,0 +1,65 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef EXTENSIONS_LOGGERCONFIG_HXX +#define EXTENSIONS_LOGGERCONFIG_HXX + +/** === begin UNO includes === **/ +#include <com/sun/star/logging/XLogger.hpp> +/** === end UNO includes === **/ + +namespace comphelper +{ + class ComponentContext; +} + +//........................................................................ +namespace logging +{ +//........................................................................ + + /** initializes the given logger from the configuration + + The configuration node /org.openoffice.Office.Logging/Settings/<logger_name> + is examined for this. If it does not yet exist, it will be created. + + The function creates a default handler and a default formatter, as specified in the + configuration. + + This function is currently external to the logger instance. Perhaps it can, on the long + run, be moved to the logger implementation - not sure if it's the best place. + */ + void initializeLoggerFromConfiguration( + const ::comphelper::ComponentContext& _rContext, + const ::com::sun::star::uno::Reference< ::com::sun::star::logging::XLogger >& _rxLogger + ); + +//........................................................................ +} // namespace logging +//........................................................................ + +#endif // EXTENSIONS_LOGGERCONFIG_HXX diff --git a/extensions/source/logging/loghandler.cxx b/extensions/source/logging/loghandler.cxx new file mode 100644 index 000000000000..082057741420 --- /dev/null +++ b/extensions/source/logging/loghandler.cxx @@ -0,0 +1,204 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#ifndef EXTENSIONS_LOGHANDLER_HXX +#include "loghandler.hxx" +#endif + +/** === begin UNO includes === **/ +#include <com/sun/star/logging/LogLevel.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/logging/PlainTextFormatter.hpp> +/** === end UNO includes === **/ + +#include <tools/diagnose_ex.h> +#include <comphelper/componentcontext.hxx> +#include <rtl/tencinfo.h> + +//........................................................................ +namespace logging +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::uno::Any; + using ::com::sun::star::logging::LogRecord; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::logging::XLogFormatter; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::lang::DisposedException; + using ::com::sun::star::logging::PlainTextFormatter; + /** === end UNO using === **/ + namespace LogLevel = ::com::sun::star::logging::LogLevel; + + //==================================================================== + //= LogHandlerHelper + //==================================================================== + //-------------------------------------------------------------------- + LogHandlerHelper::LogHandlerHelper( const Reference< XComponentContext >& _rxContext, ::osl::Mutex& _rMutex, ::cppu::OBroadcastHelper& _rBHelper ) + :m_eEncoding( RTL_TEXTENCODING_UTF8 ) + ,m_nLevel( LogLevel::SEVERE ) + ,m_xFormatter( NULL ) + ,m_xContext( _rxContext ) + ,m_rMutex( _rMutex ) + ,m_rBHelper( _rBHelper ) + ,m_bInitialized( false ) + { + } + + //-------------------------------------------------------------------- + void LogHandlerHelper::initFromSettings( const ::comphelper::NamedValueCollection& _rSettings ) + { + ::rtl::OUString sEncoding; + if ( _rSettings.get_ensureType( "Encoding", sEncoding ) ) + { + if ( !setEncoding( sEncoding ) ) + throw IllegalArgumentException(); + } + + _rSettings.get_ensureType( "Formatter", m_xFormatter ); + _rSettings.get_ensureType( "Level", m_nLevel ); + } + + //-------------------------------------------------------------------- + void LogHandlerHelper::enterMethod() + { + m_rMutex.acquire(); + + if ( !getIsInitialized() ) + throw DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "component not initialized" ) ), NULL ); + + if ( m_rBHelper.bDisposed ) + throw DisposedException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "component already disposed" ) ), NULL ); + + // fallback settings, in case they weren't passed at construction time + if ( !getFormatter().is() ) + { + try + { + Reference< XLogFormatter > xFormatter( PlainTextFormatter::create( m_xContext ), UNO_QUERY_THROW ); + setFormatter( xFormatter ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + + //-------------------------------------------------------------------- + bool LogHandlerHelper::getEncoding( ::rtl::OUString& _out_rEncoding ) const + { + const char* pMimeCharset = rtl_getMimeCharsetFromTextEncoding( m_eEncoding ); + if ( pMimeCharset ) + { + _out_rEncoding = ::rtl::OUString::createFromAscii( pMimeCharset ); + return true; + } + _out_rEncoding = ::rtl::OUString(); + return false; + } + + //-------------------------------------------------------------------- + bool LogHandlerHelper::setEncoding( const ::rtl::OUString& _rEncoding ) + { + ::rtl::OString sAsciiEncoding( ::rtl::OUStringToOString( _rEncoding, RTL_TEXTENCODING_ASCII_US ) ); + rtl_TextEncoding eEncoding = rtl_getTextEncodingFromMimeCharset( sAsciiEncoding.getStr() ); + if ( eEncoding != RTL_TEXTENCODING_DONTKNOW ) + { + m_eEncoding = eEncoding; + return true; + } + return false; + } + + //-------------------------------------------------------------------- + bool LogHandlerHelper::formatForPublishing( const LogRecord& _rRecord, ::rtl::OString& _out_rEntry ) const + { + if ( _rRecord.Level < getLevel() ) + // not to be published due to low level + return false; + + try + { + Reference< XLogFormatter > xFormatter( getFormatter(), UNO_QUERY_THROW ); + ::rtl::OUString sEntry( xFormatter->format( _rRecord ) ); + _out_rEntry = ::rtl::OUStringToOString( sEntry, getTextEncoding() ); + return true; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return false; + } + + //-------------------------------------------------------------------- + bool LogHandlerHelper::getEncodedHead( ::rtl::OString& _out_rHead ) const + { + try + { + Reference< XLogFormatter > xFormatter( getFormatter(), UNO_QUERY_THROW ); + ::rtl::OUString sHead( xFormatter->getHead() ); + _out_rHead = ::rtl::OUStringToOString( sHead, getTextEncoding() ); + return true; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return false; + } + + //-------------------------------------------------------------------- + bool LogHandlerHelper::getEncodedTail( ::rtl::OString& _out_rTail ) const + { + try + { + Reference< XLogFormatter > xFormatter( getFormatter(), UNO_QUERY_THROW ); + ::rtl::OUString sTail( xFormatter->getTail() ); + _out_rTail = ::rtl::OUStringToOString( sTail, getTextEncoding() ); + return true; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return false; + } + +//........................................................................ +} // namespace logging +//........................................................................ + diff --git a/extensions/source/logging/loghandler.hxx b/extensions/source/logging/loghandler.hxx new file mode 100644 index 000000000000..3927a0008f08 --- /dev/null +++ b/extensions/source/logging/loghandler.hxx @@ -0,0 +1,154 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef LOGHANDLER_HXX +#define LOGHANDLER_HXX + +/** === begin UNO includes === **/ +#include <com/sun/star/logging/XLogFormatter.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/logging/LogRecord.hpp> +/** === end UNO includes === **/ + +#include <comphelper/namedvaluecollection.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <rtl/string.hxx> + +//........................................................................ +namespace logging +{ +//........................................................................ + + //==================================================================== + //= + //==================================================================== + class LogHandlerHelper + { + private: + // <attributes> + rtl_TextEncoding m_eEncoding; + sal_Int32 m_nLevel; + ::com::sun::star::uno::Reference< ::com::sun::star::logging::XLogFormatter > + m_xFormatter; + // <//attributes> + + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > + m_xContext; + ::osl::Mutex& m_rMutex; + ::cppu::OBroadcastHelper& m_rBHelper; + bool m_bInitialized; + + public: + LogHandlerHelper( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext, + ::osl::Mutex& _rMutex, + ::cppu::OBroadcastHelper& _rBHelper + ); + + public: + bool getIsInitialized() const { return m_bInitialized; } + void setIsInitialized() { m_bInitialized = true; } + + bool getEncoding( ::rtl::OUString& _out_rEncoding ) const; + bool setEncoding( const ::rtl::OUString& _rEncoding ); + + inline rtl_TextEncoding + getTextEncoding() const { return m_eEncoding; } + + inline ::com::sun::star::uno::Reference< ::com::sun::star::logging::XLogFormatter > + getFormatter() const { return m_xFormatter; } + inline void + setFormatter( const ::com::sun::star::uno::Reference< ::com::sun::star::logging::XLogFormatter >& _rxFormatter ) + { + m_xFormatter = _rxFormatter; + } + + inline sal_Int32 + getLevel() const { return m_nLevel; } + inline void + setLevel( const sal_Int32 _nLevel ) + { + m_nLevel = _nLevel; + } + + /** prepares implementation of an public accessible method of a log handler + + <code>enterMethod</code> does the following things: + <ul><li>It acquires the mutex given in the constructor.</li> + <li>It checks whether the component is already initialized, and throws an exception if not os.</li> + <li>It checks whether the component is already disposed, and throws an exception if not os.</li> + <li>It creates a default formatter (PlainTextFormatter), if no formatter exists at this time.</li> + </ul> + */ + void enterMethod(); + + /** formats a record for publishing it + + The method first checks whether the records log level is greater or equal our own + log level. If not, <FALSE/> is returned. + + Second, our formatter is used to create a unicode string from the log record. If an error occurs + during this, e.g. if the formatter is <NULL/> or throws an exception during formatting, + <FALSE/> is returned. + + Finally, the unicode string is encoded into a byte string, using our encoding setting. Then, + <TRUE/> is returned. + */ + bool formatForPublishing( const ::com::sun::star::logging::LogRecord& _rRecord, ::rtl::OString& _out_rEntry ) const; + + /** retrieves our formatter's heading, encoded with our encoding + + @return <TRUE/> in case of success, <FALSE/> if any error occured + */ + bool getEncodedHead( ::rtl::OString& _out_rHead ) const; + + /** retrieves our formatter's tail, encoded with our encoding + + @return <TRUE/> in case of success, <FALSE/> if any error occured + */ + bool getEncodedTail( ::rtl::OString& _out_rTail ) const; + + /** initializes the instance from a collection of named settings + + The recognized named settings are <code>Encoding</code>, <code>Formatter</code>, and <code>Level</code>, + which initialize the respective attributes. + + Settings which are recognized are remove from the given collection. This allows + the caller to determine whether or not the collection contained any unsupported + items, and react appropriately. + + @throws IllegalArgumentException + if one of the values in the collection is of wrong type. + */ + void initFromSettings( const ::comphelper::NamedValueCollection& _rSettings ); + }; + +//........................................................................ +} // namespace logging +//........................................................................ + +#endif // LOGHANDLER_HXX diff --git a/extensions/source/logging/logrecord.cxx b/extensions/source/logging/logrecord.cxx new file mode 100644 index 000000000000..cac9fe79e459 --- /dev/null +++ b/extensions/source/logging/logrecord.cxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" +#include "logrecord.hxx" + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ + +#include <osl/time.h> +#include <osl/thread.h> +#include <osl/diagnose.h> + +//........................................................................ +namespace logging +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::logging::LogRecord; + using ::com::sun::star::util::DateTime; + /** === end UNO using === **/ + + //==================================================================== + //= helper + //==================================================================== + //-------------------------------------------------------------------- + namespace + { + /** returns a string representation of the current thread + + @todo + We need a way to retrieve the current UNO thread ID as string, + which is issue #i77342# + */ + ::rtl::OUString getCurrentThreadID() + { + oslThreadIdentifier nThreadID( osl_getThreadIdentifier( NULL ) ); + return ::rtl::OUString::valueOf( (sal_Int64)nThreadID ); + } + } + + //-------------------------------------------------------------------- + LogRecord createLogRecord( const ::rtl::OUString& _rLoggerName, const ::rtl::OUString& _rClassName, + const ::rtl::OUString& _rMethodName, const ::rtl::OUString& _rMessage, + sal_Int32 _nLogLevel, oslInterlockedCount _nEventNumber ) + { + TimeValue aTimeValue; + osl_getSystemTime( &aTimeValue ); + + oslDateTime aDateTime; + OSL_VERIFY( osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime ) ); + + DateTime aTimeStamp; + aTimeStamp.Year = aDateTime.Year; + aTimeStamp.Month = aDateTime.Month; + aTimeStamp.Day = aDateTime.Day; + aTimeStamp.Hours = aDateTime.Hours; + aTimeStamp.Minutes = aDateTime.Minutes; + aTimeStamp.Seconds = aDateTime.Seconds; + aTimeStamp.HundredthSeconds = ::sal::static_int_cast< sal_Int16 >( aDateTime.NanoSeconds / 10000000 ); + + return LogRecord( + _rLoggerName, + _rClassName, + _rMethodName, + _rMessage, + aTimeStamp, + _nEventNumber, + getCurrentThreadID(), + _nLogLevel + ); + } + +//........................................................................ +} // namespace logging +//........................................................................ + diff --git a/extensions/source/logging/logrecord.hxx b/extensions/source/logging/logrecord.hxx new file mode 100644 index 000000000000..6503e5c48de7 --- /dev/null +++ b/extensions/source/logging/logrecord.hxx @@ -0,0 +1,68 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef LOGRECORD_HXX +#define LOGRECORD_HXX + +/** === begin UNO includes === **/ +#include <com/sun/star/logging/LogRecord.hpp> +/** === end UNO includes === **/ + +#include <osl/interlck.h> + +//........................................................................ +namespace logging +{ +//........................................................................ + + //==================================================================== + //= helper + //==================================================================== + ::com::sun::star::logging::LogRecord createLogRecord( + const ::rtl::OUString& _rLoggerName, + const ::rtl::OUString& _rClassName, + const ::rtl::OUString& _rMethodName, + const ::rtl::OUString& _rMessage, + sal_Int32 _nLogLevel, + oslInterlockedCount _nEventNumber + ); + + inline ::com::sun::star::logging::LogRecord createLogRecord( + const ::rtl::OUString& _rLoggerName, + const ::rtl::OUString& _rMessage, + sal_Int32 _nLogLevel, + oslInterlockedCount _nEventNumber + ) + { + return createLogRecord( _rLoggerName, ::rtl::OUString(), ::rtl::OUString(), _rMessage, _nLogLevel, _nEventNumber ); + } + +//........................................................................ +} // namespace logging +//........................................................................ + +#endif // LOGRECORD_HXX diff --git a/extensions/source/logging/makefile.mk b/extensions/source/logging/makefile.mk new file mode 100644 index 000000000000..1436576e89ba --- /dev/null +++ b/extensions/source/logging/makefile.mk @@ -0,0 +1,84 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJNAME=extensions +TARGET=log + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk + +# --- Files ------------------------------------- + +# ... object files ............................ +EXCEPTIONSFILES= \ + $(SLO)$/consolehandler.obj \ + $(SLO)$/csvformatter.obj \ + $(SLO)$/filehandler.obj \ + $(SLO)$/log_services.obj \ + $(SLO)$/logger.obj \ + $(SLO)$/loggerconfig.obj \ + $(SLO)$/loghandler.obj \ + $(SLO)$/plaintextformatter.obj \ + +SLOFILES= \ + $(EXCEPTIONSFILES) \ + $(SLO)$/log_module.obj \ + $(SLO)$/logrecord.obj \ + +# --- library ----------------------------------- + +LIB1TARGET=$(SLB)$/$(TARGET)_t.lib +LIB1FILES=\ + $(SLB)$/$(TARGET).lib + +SHL1TARGET=$(TARGET)$(DLLPOSTFIX) + +SHL1STDLIBS= \ + $(COMPHELPERLIB) \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) + +SHL1LIBS=$(LIB1TARGET) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) +SHL1VERSIONMAP=$(SOLARENV)/src/component.map + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + + +ALLTAR : $(MISC)/log.component + +$(MISC)/log.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \ + log.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt log.component diff --git a/extensions/source/logging/methodguard.hxx b/extensions/source/logging/methodguard.hxx new file mode 100644 index 000000000000..2b7a209a9bdf --- /dev/null +++ b/extensions/source/logging/methodguard.hxx @@ -0,0 +1,73 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef EXTENSIONS_METHODGUARD_HXX +#define EXTENSIONS_METHODGUARD_HXX + +/** === begin UNO includes === **/ +/** === end UNO includes === **/ + +//........................................................................ +namespace logging +{ +//........................................................................ + + //==================================================================== + //= ComponentMethodGuard + //==================================================================== + template < class COMPONENT > + class ComponentMethodGuard + { + private: + COMPONENT& m_rHandler; + + public: + class Access + { + private: + friend class ComponentMethodGuard; + Access() { } + }; + + public: + ComponentMethodGuard( COMPONENT& _rHandler ) + :m_rHandler( _rHandler ) + { + m_rHandler.enterMethod( Access() ); + } + ~ComponentMethodGuard() + { + m_rHandler.leaveMethod( Access() ); + } + }; + +//........................................................................ +} // namespace logging +//........................................................................ + +#endif // EXTENSIONS_METHODGUARD_HXX + diff --git a/extensions/source/logging/plaintextformatter.cxx b/extensions/source/logging/plaintextformatter.cxx new file mode 100644 index 000000000000..fd0c96e2da8e --- /dev/null +++ b/extensions/source/logging/plaintextformatter.cxx @@ -0,0 +1,226 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#include "log_module.hxx" + +#include <stdio.h> + +/** === begin UNO includes === **/ +#include <com/sun/star/logging/XLogFormatter.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +/** === end UNO includes === **/ + +#include <comphelper/componentcontext.hxx> + +#include <cppuhelper/implbase2.hxx> + +#include <rtl/ustrbuf.hxx> + +#include <osl/thread.h> + +//........................................................................ +namespace logging +{ +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::logging::XLogFormatter; + using ::com::sun::star::uno::XComponentContext; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::lang::XServiceInfo; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::logging::LogRecord; + using ::com::sun::star::uno::XInterface; + /** === end UNO using === **/ + + //==================================================================== + //= PlainTextFormatter - declaration + //==================================================================== + typedef ::cppu::WeakImplHelper2 < XLogFormatter + , XServiceInfo + > PlainTextFormatter_Base; + class PlainTextFormatter : public PlainTextFormatter_Base + { + private: + ::comphelper::ComponentContext m_aContext; + + protected: + PlainTextFormatter( const Reference< XComponentContext >& _rxContext ); + virtual ~PlainTextFormatter(); + + // XLogFormatter + virtual ::rtl::OUString SAL_CALL getHead( ) throw (RuntimeException); + virtual ::rtl::OUString SAL_CALL format( const LogRecord& Record ) throw (RuntimeException); + virtual ::rtl::OUString SAL_CALL getTail( ) throw (RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException); + virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); + + public: + // XServiceInfo - static version + static ::rtl::OUString SAL_CALL getImplementationName_static(); + static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext ); + }; + + //==================================================================== + //= PlainTextFormatter - implementation + //==================================================================== + //-------------------------------------------------------------------- + PlainTextFormatter::PlainTextFormatter( const Reference< XComponentContext >& _rxContext ) + :m_aContext( _rxContext ) + { + } + + //-------------------------------------------------------------------- + PlainTextFormatter::~PlainTextFormatter() + { + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL PlainTextFormatter::getHead( ) throw (RuntimeException) + { + ::rtl::OUStringBuffer aHeader; + aHeader.appendAscii( " event no" ); // column 1: the event number + aHeader.appendAscii( " " ); + aHeader.appendAscii( "thread " ); // column 2: the thread ID + aHeader.appendAscii( " " ); + aHeader.appendAscii( "date " ); // column 3: date + aHeader.appendAscii( " " ); + aHeader.appendAscii( "time " ); // column 4: time + aHeader.appendAscii( " " ); + aHeader.appendAscii( "(class/method:) message" ); // column 5: class/method/message + aHeader.appendAscii( "\n" ); + return aHeader.makeStringAndClear(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL PlainTextFormatter::format( const LogRecord& _rRecord ) throw (RuntimeException) + { + char buffer[ 30 ]; + const int buffer_size = sizeof( buffer ); + int used = snprintf( buffer, buffer_size, "%10i", (int)_rRecord.SequenceNumber ); + if ( used >= buffer_size || used < 0 ) + buffer[ buffer_size - 1 ] = 0; + + ::rtl::OUStringBuffer aLogEntry; + aLogEntry.appendAscii( buffer ); + aLogEntry.appendAscii( " " ); + + ::rtl::OString sThreadID( ::rtl::OUStringToOString( _rRecord.ThreadID, osl_getThreadTextEncoding() ) ); + snprintf( buffer, buffer_size, "%8s", sThreadID.getStr() ); + aLogEntry.appendAscii( buffer ); + aLogEntry.appendAscii( " " ); + + snprintf( buffer, buffer_size, "%04i-%02i-%02i %02i:%02i:%02i.%02i", + (int)_rRecord.LogTime.Year, (int)_rRecord.LogTime.Month, (int)_rRecord.LogTime.Day, + (int)_rRecord.LogTime.Hours, (int)_rRecord.LogTime.Minutes, (int)_rRecord.LogTime.Seconds, (int)_rRecord.LogTime.HundredthSeconds ); + aLogEntry.appendAscii( buffer ); + aLogEntry.appendAscii( " " ); + + if ( _rRecord.SourceClassName.getLength() && _rRecord.SourceMethodName.getLength() ) + { + aLogEntry.append( _rRecord.SourceClassName ); + aLogEntry.appendAscii( "::" ); + aLogEntry.append( _rRecord.SourceMethodName ); + aLogEntry.appendAscii( ": " ); + } + + aLogEntry.append( _rRecord.Message ); + aLogEntry.appendAscii( "\n" ); + + return aLogEntry.makeStringAndClear(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL PlainTextFormatter::getTail( ) throw (RuntimeException) + { + // no tail + return ::rtl::OUString(); + } + + //-------------------------------------------------------------------- + ::sal_Bool SAL_CALL PlainTextFormatter::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException) + { + const Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames() ); + for ( const ::rtl::OUString* pServiceNames = aServiceNames.getConstArray(); + pServiceNames != aServiceNames.getConstArray() + aServiceNames.getLength(); + ++pServiceNames + ) + if ( _rServiceName == *pServiceNames ) + return sal_True; + return sal_False; + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL PlainTextFormatter::getImplementationName() throw(RuntimeException) + { + return getImplementationName_static(); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL PlainTextFormatter::getSupportedServiceNames() throw(RuntimeException) + { + return getSupportedServiceNames_static(); + } + + //-------------------------------------------------------------------- + ::rtl::OUString SAL_CALL PlainTextFormatter::getImplementationName_static() + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.PlainTextFormatter" ) ); + } + + //-------------------------------------------------------------------- + Sequence< ::rtl::OUString > SAL_CALL PlainTextFormatter::getSupportedServiceNames_static() + { + Sequence< ::rtl::OUString > aServiceNames(1); + aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.PlainTextFormatter" ) ); + return aServiceNames; + } + + //-------------------------------------------------------------------- + Reference< XInterface > PlainTextFormatter::Create( const Reference< XComponentContext >& _rxContext ) + { + return *( new PlainTextFormatter( _rxContext ) ); + } + + //-------------------------------------------------------------------- + void createRegistryInfo_PlainTextFormatter() + { + static OAutoRegistration< PlainTextFormatter > aAutoRegistration; + } + +//........................................................................ +} // namespace logging +//........................................................................ |