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