1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_extensions.hxx" 30 31 #include "log_module.hxx" 32 #include "logrecord.hxx" 33 #include "loggerconfig.hxx" 34 35 /** === begin UNO includes === **/ 36 #include <com/sun/star/logging/XLogger.hpp> 37 #include <com/sun/star/logging/LogLevel.hpp> 38 #include <com/sun/star/uno/XComponentContext.hpp> 39 #include <com/sun/star/lang/XServiceInfo.hpp> 40 #include <com/sun/star/logging/XLoggerPool.hpp> 41 /** === end UNO includes === **/ 42 43 #include <tools/diagnose_ex.h> 44 45 #include <comphelper/componentcontext.hxx> 46 47 #include <cppuhelper/basemutex.hxx> 48 #include <cppuhelper/interfacecontainer.hxx> 49 #include <cppuhelper/implbase2.hxx> 50 #include <cppuhelper/weakref.hxx> 51 52 #include <boost/bind.hpp> 53 54 #include <map> 55 56 //........................................................................ 57 namespace logging 58 { 59 //........................................................................ 60 61 /** === begin UNO using === **/ 62 using ::com::sun::star::logging::XLogger; 63 using ::com::sun::star::uno::Reference; 64 using ::com::sun::star::uno::XComponentContext; 65 using ::com::sun::star::lang::XServiceInfo; 66 using ::com::sun::star::uno::RuntimeException; 67 using ::com::sun::star::uno::Sequence; 68 using ::com::sun::star::uno::XInterface; 69 using ::com::sun::star::uno::UNO_QUERY_THROW; 70 using ::com::sun::star::uno::Any; 71 using ::com::sun::star::uno::Exception; 72 using ::com::sun::star::uno::WeakReference; 73 using ::com::sun::star::logging::XLogHandler; 74 using ::com::sun::star::logging::XLoggerPool; 75 using ::com::sun::star::logging::LogRecord; 76 /** === end UNO using === **/ 77 namespace LogLevel = ::com::sun::star::logging::LogLevel; 78 79 //==================================================================== 80 //= helper 81 //==================================================================== 82 namespace 83 { 84 sal_Bool lcl_supportsService_nothrow( XServiceInfo& _rSI, const ::rtl::OUString& _rServiceName ) 85 { 86 const Sequence< ::rtl::OUString > aServiceNames( _rSI.getSupportedServiceNames() ); 87 for ( const ::rtl::OUString* pServiceNames = aServiceNames.getConstArray(); 88 pServiceNames != aServiceNames.getConstArray() + aServiceNames.getLength(); 89 ++pServiceNames 90 ) 91 if ( _rServiceName == *pServiceNames ) 92 return sal_True; 93 return sal_False; 94 } 95 } 96 97 //==================================================================== 98 //= EventLogger - declaration 99 //==================================================================== 100 typedef ::cppu::WeakImplHelper2 < XLogger 101 , XServiceInfo 102 > EventLogger_Base; 103 class EventLogger :public ::cppu::BaseMutex 104 ,public EventLogger_Base 105 { 106 private: 107 ::comphelper::ComponentContext m_aContext; 108 ::cppu::OInterfaceContainerHelper m_aHandlers; 109 oslInterlockedCount m_nEventNumber; 110 111 // <attributes> 112 sal_Int32 m_nLogLevel; 113 ::rtl::OUString m_sName; 114 // </attributes> 115 116 public: 117 EventLogger( const Reference< XComponentContext >& _rxContext, const ::rtl::OUString& _rName ); 118 119 // XServiceInfo 120 virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException); 121 virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException); 122 virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); 123 124 // XLogger 125 virtual ::rtl::OUString SAL_CALL getName() throw (RuntimeException); 126 virtual ::sal_Int32 SAL_CALL getLevel() throw (RuntimeException); 127 virtual void SAL_CALL setLevel( ::sal_Int32 _level ) throw (RuntimeException); 128 virtual void SAL_CALL addLogHandler( const Reference< XLogHandler >& LogHandler ) throw (RuntimeException); 129 virtual void SAL_CALL removeLogHandler( const Reference< XLogHandler >& LogHandler ) throw (RuntimeException); 130 virtual ::sal_Bool SAL_CALL isLoggable( ::sal_Int32 _nLevel ) throw (RuntimeException); 131 virtual void SAL_CALL log( ::sal_Int32 Level, const ::rtl::OUString& Message ) throw (RuntimeException); 132 virtual void SAL_CALL logp( ::sal_Int32 Level, const ::rtl::OUString& SourceClass, const ::rtl::OUString& SourceMethod, const ::rtl::OUString& Message ) throw (RuntimeException); 133 134 protected: 135 ~EventLogger(); 136 137 private: 138 /** logs the given log record 139 */ 140 void impl_ts_logEvent_nothrow( const LogRecord& _rRecord ); 141 142 /** non-threadsafe impl-version of isLoggable 143 */ 144 bool impl_nts_isLoggable_nothrow( ::sal_Int32 _nLevel ); 145 }; 146 147 //==================================================================== 148 //= LoggerPool - declaration 149 //==================================================================== 150 typedef ::cppu::WeakImplHelper2 < XLoggerPool 151 , XServiceInfo 152 > LoggerPool_Base; 153 /** administrates a pool of XLogger instances, where a logger is keyed by its name, 154 and subsequent requests for a logger with the same name return the same instance. 155 */ 156 class LoggerPool : public LoggerPool_Base 157 { 158 private: 159 typedef ::std::map< ::rtl::OUString, WeakReference< XLogger > > ImplPool; 160 161 private: 162 ::osl::Mutex m_aMutex; 163 ::comphelper::ComponentContext m_aContext; 164 ImplPool m_aImpl; 165 166 public: 167 LoggerPool( const Reference< XComponentContext >& _rxContext ); 168 169 // XServiceInfo 170 virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException); 171 virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException); 172 virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); 173 174 // helper for factories 175 static Sequence< ::rtl::OUString > getSupportedServiceNames_static(); 176 static ::rtl::OUString getImplementationName_static(); 177 static ::rtl::OUString getSingletonName_static(); 178 static Reference< XInterface > Create( const Reference< XComponentContext >& _rxContext ); 179 180 // XLoggerPool 181 virtual Reference< XLogger > SAL_CALL getNamedLogger( const ::rtl::OUString& Name ) throw (RuntimeException); 182 virtual Reference< XLogger > SAL_CALL getDefaultLogger( ) throw (RuntimeException); 183 }; 184 185 //==================================================================== 186 //= EventLogger - implementation 187 //==================================================================== 188 //-------------------------------------------------------------------- 189 EventLogger::EventLogger( const Reference< XComponentContext >& _rxContext, const ::rtl::OUString& _rName ) 190 :m_aContext( _rxContext ) 191 ,m_aHandlers( m_aMutex ) 192 ,m_nEventNumber( 0 ) 193 ,m_nLogLevel( LogLevel::OFF ) 194 ,m_sName( _rName ) 195 { 196 osl_incrementInterlockedCount( &m_refCount ); 197 { 198 initializeLoggerFromConfiguration( m_aContext, this ); 199 } 200 osl_decrementInterlockedCount( &m_refCount ); 201 } 202 203 //-------------------------------------------------------------------- 204 EventLogger::~EventLogger() 205 { 206 } 207 208 //-------------------------------------------------------------------- 209 bool EventLogger::impl_nts_isLoggable_nothrow( ::sal_Int32 _nLevel ) 210 { 211 if ( _nLevel < m_nLogLevel ) 212 return false; 213 214 if ( !m_aHandlers.getLength() ) 215 return false; 216 217 return true; 218 } 219 220 //-------------------------------------------------------------------- 221 void EventLogger::impl_ts_logEvent_nothrow( const LogRecord& _rRecord ) 222 { 223 ::osl::MutexGuard aGuard( m_aMutex ); 224 225 if ( !impl_nts_isLoggable_nothrow( _rRecord.Level ) ) 226 return; 227 228 m_aHandlers.forEach< XLogHandler >( 229 ::boost::bind( &XLogHandler::publish, _1, ::boost::cref( _rRecord ) ) ); 230 m_aHandlers.forEach< XLogHandler >( 231 ::boost::bind( &XLogHandler::flush, _1 ) ); 232 } 233 234 //-------------------------------------------------------------------- 235 ::rtl::OUString SAL_CALL EventLogger::getName() throw (RuntimeException) 236 { 237 return m_sName; 238 } 239 240 //-------------------------------------------------------------------- 241 ::sal_Int32 SAL_CALL EventLogger::getLevel() throw (RuntimeException) 242 { 243 ::osl::MutexGuard aGuard( m_aMutex ); 244 return m_nLogLevel; 245 } 246 247 //-------------------------------------------------------------------- 248 void SAL_CALL EventLogger::setLevel( ::sal_Int32 _level ) throw (RuntimeException) 249 { 250 ::osl::MutexGuard aGuard( m_aMutex ); 251 m_nLogLevel = _level; 252 } 253 254 //-------------------------------------------------------------------- 255 void SAL_CALL EventLogger::addLogHandler( const Reference< XLogHandler >& _rxLogHandler ) throw (RuntimeException) 256 { 257 if ( _rxLogHandler.is() ) 258 m_aHandlers.addInterface( _rxLogHandler ); 259 } 260 261 //-------------------------------------------------------------------- 262 void SAL_CALL EventLogger::removeLogHandler( const Reference< XLogHandler >& _rxLogHandler ) throw (RuntimeException) 263 { 264 if ( _rxLogHandler.is() ) 265 m_aHandlers.removeInterface( _rxLogHandler ); 266 } 267 268 //-------------------------------------------------------------------- 269 ::sal_Bool SAL_CALL EventLogger::isLoggable( ::sal_Int32 _nLevel ) throw (RuntimeException) 270 { 271 ::osl::MutexGuard aGuard( m_aMutex ); 272 return impl_nts_isLoggable_nothrow( _nLevel ); 273 } 274 275 //-------------------------------------------------------------------- 276 void SAL_CALL EventLogger::log( ::sal_Int32 _nLevel, const ::rtl::OUString& _rMessage ) throw (RuntimeException) 277 { 278 impl_ts_logEvent_nothrow( createLogRecord( 279 m_sName, 280 _rMessage, 281 _nLevel, 282 osl_incrementInterlockedCount( &m_nEventNumber ) 283 ) ); 284 } 285 286 //-------------------------------------------------------------------- 287 void SAL_CALL EventLogger::logp( ::sal_Int32 _nLevel, const ::rtl::OUString& _rSourceClass, const ::rtl::OUString& _rSourceMethod, const ::rtl::OUString& _rMessage ) throw (RuntimeException) 288 { 289 impl_ts_logEvent_nothrow( createLogRecord( 290 m_sName, 291 _rSourceClass, 292 _rSourceMethod, 293 _rMessage, 294 _nLevel, 295 osl_incrementInterlockedCount( &m_nEventNumber ) 296 ) ); 297 } 298 299 //-------------------------------------------------------------------- 300 ::rtl::OUString SAL_CALL EventLogger::getImplementationName() throw(RuntimeException) 301 { 302 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.EventLogger" ) ); 303 } 304 305 //-------------------------------------------------------------------- 306 ::sal_Bool EventLogger::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException) 307 { 308 return lcl_supportsService_nothrow( *this, _rServiceName ); 309 } 310 311 //-------------------------------------------------------------------- 312 Sequence< ::rtl::OUString > SAL_CALL EventLogger::getSupportedServiceNames() throw(RuntimeException) 313 { 314 Sequence< ::rtl::OUString > aServiceNames(1); 315 aServiceNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.Logger" ) ); 316 return aServiceNames; 317 } 318 319 //==================================================================== 320 //= LoggerPool - implementation 321 //==================================================================== 322 //-------------------------------------------------------------------- 323 LoggerPool::LoggerPool( const Reference< XComponentContext >& _rxContext ) 324 :m_aContext( _rxContext ) 325 { 326 } 327 328 //-------------------------------------------------------------------- 329 ::rtl::OUString SAL_CALL LoggerPool::getImplementationName() throw(RuntimeException) 330 { 331 return getImplementationName_static(); 332 } 333 334 //-------------------------------------------------------------------- 335 ::sal_Bool SAL_CALL LoggerPool::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException) 336 { 337 return lcl_supportsService_nothrow( *this, _rServiceName ); 338 } 339 340 //-------------------------------------------------------------------- 341 Sequence< ::rtl::OUString > SAL_CALL LoggerPool::getSupportedServiceNames() throw(RuntimeException) 342 { 343 return getSupportedServiceNames_static(); 344 } 345 346 //-------------------------------------------------------------------- 347 ::rtl::OUString SAL_CALL LoggerPool::getImplementationName_static() 348 { 349 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.LoggerPool" ) ); 350 } 351 352 //-------------------------------------------------------------------- 353 Sequence< ::rtl::OUString > SAL_CALL LoggerPool::getSupportedServiceNames_static() 354 { 355 Sequence< ::rtl::OUString > aServiceNames(1); 356 aServiceNames[0] = getSingletonName_static(); 357 return aServiceNames; 358 } 359 360 //-------------------------------------------------------------------- 361 ::rtl::OUString LoggerPool::getSingletonName_static() 362 { 363 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.LoggerPool" ) ); 364 } 365 366 //-------------------------------------------------------------------- 367 Reference< XInterface > SAL_CALL LoggerPool::Create( const Reference< XComponentContext >& _rxContext ) 368 { 369 return *( new LoggerPool( _rxContext ) ); 370 } 371 372 //-------------------------------------------------------------------- 373 Reference< XLogger > SAL_CALL LoggerPool::getNamedLogger( const ::rtl::OUString& _rName ) throw (RuntimeException) 374 { 375 ::osl::MutexGuard aGuard( m_aMutex ); 376 377 WeakReference< XLogger >& rLogger( m_aImpl[ _rName ] ); 378 Reference< XLogger > xLogger( (Reference< XLogger >)rLogger ); 379 if ( !xLogger.is() ) 380 { 381 // never requested before, or already dead 382 xLogger = new EventLogger( m_aContext.getUNOContext(), _rName ); 383 rLogger = xLogger; 384 } 385 386 return xLogger; 387 } 388 389 //-------------------------------------------------------------------- 390 Reference< XLogger > SAL_CALL LoggerPool::getDefaultLogger( ) throw (RuntimeException) 391 { 392 return getNamedLogger( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.logging.DefaultLogger" ) ) ); 393 } 394 395 //-------------------------------------------------------------------- 396 void createRegistryInfo_LoggerPool() 397 { 398 static OSingletonRegistration< LoggerPool > aAutoRegistration; 399 } 400 401 //........................................................................ 402 } // namespace logging 403 //........................................................................ 404 405