add front demo in this project

This commit is contained in:
lnk
2025-06-20 16:20:59 +08:00
parent 768eebbc2b
commit e14e3f9678
208 changed files with 54655 additions and 114 deletions

View File

@@ -0,0 +1,88 @@
// -*- C++ -*-
// Module: Log4CPLUS
// File: appenderattachable.h
// Created: 6/2001
// Author: Tad E. Smith
//
//
// Copyright 2001-2017 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/** @file */
#ifndef LOG4CPLUS_SPI_APPENDER_ATTACHABLE_HEADER_
#define LOG4CPLUS_SPI_APPENDER_ATTACHABLE_HEADER_
#include <log4cplus/config.hxx>
#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
#pragma once
#endif
#include <log4cplus/appender.h>
#include <log4cplus/tstring.h>
#include <log4cplus/helpers/pointer.h>
#include <vector>
namespace log4cplus {
// Forward Declarations
typedef std::vector<log4cplus::SharedAppenderPtr> SharedAppenderPtrList;
namespace spi {
/**
* This Interface is for attaching Appenders to objects.
*/
class LOG4CPLUS_EXPORT AppenderAttachable {
public:
// Methods
/**
* Add an appender.
*/
virtual void addAppender(SharedAppenderPtr newAppender) = 0;
/**
* Get all previously added appenders as an Enumeration.
*/
virtual SharedAppenderPtrList getAllAppenders() = 0;
/**
* Get an appender by name.
*/
virtual SharedAppenderPtr getAppender(const log4cplus::tstring& name) = 0;
/**
* Remove all previously added appenders.
*/
virtual void removeAllAppenders() = 0;
/**
* Remove the appender passed as parameter from the list of appenders.
*/
virtual void removeAppender(SharedAppenderPtr appender) = 0;
/**
* Remove the appender with the name passed as parameter from the
* list of appenders.
*/
virtual void removeAppender(const log4cplus::tstring& name) = 0;
// Dtor
virtual ~AppenderAttachable() = 0;
};
} // end namespace spi
} // end namespace log4cplus
#endif // LOG4CPLUS_SPI_APPENDER_ATTACHABLE_HEADER_

View File

@@ -0,0 +1,275 @@
// -*- C++ -*-
// Module: Log4CPLUS
// File: factory.h
// Created: 2/2002
// Author: Tad E. Smith
//
//
// Copyright 2002-2017 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/** @file */
#ifndef LOG4CPLUS_SPI_FACTORY_HEADER_
#define LOG4CPLUS_SPI_FACTORY_HEADER_
#include <log4cplus/config.hxx>
#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
#pragma once
#endif
#include <log4cplus/appender.h>
#include <log4cplus/layout.h>
#include <log4cplus/tstring.h>
#include <log4cplus/spi/filter.h>
#include <log4cplus/spi/objectregistry.h>
#include <memory>
#include <vector>
#include <locale>
namespace log4cplus {
namespace spi {
/**
* This is the base class for all factories.
*/
class LOG4CPLUS_EXPORT BaseFactory {
public:
virtual ~BaseFactory() = 0;
/**
* Returns the typename of the objects this factory creates.
*/
virtual log4cplus::tstring const & getTypeName() const = 0;
};
/**
* This abstract class defines the "Factory" interface to create "Appender"
* objects.
*/
class LOG4CPLUS_EXPORT AppenderFactory : public BaseFactory {
public:
typedef Appender ProductType;
typedef SharedAppenderPtr ProductPtr;
AppenderFactory();
virtual ~AppenderFactory() = 0;
/**
* Create an "Appender" object.
*/
virtual SharedAppenderPtr createObject(const log4cplus::helpers::Properties& props) = 0;
};
/**
* This abstract class defines the "Factory" interface to create "Layout"
* objects.
*/
class LOG4CPLUS_EXPORT LayoutFactory : public BaseFactory {
public:
typedef Layout ProductType;
typedef std::unique_ptr<Layout> ProductPtr;
LayoutFactory();
virtual ~LayoutFactory() = 0;
/**
* Create a "Layout" object.
*/
virtual std::unique_ptr<Layout> createObject(const log4cplus::helpers::Properties& props) = 0;
};
/**
* This abstract class defines the "Factory" interface to create "Appender"
* objects.
*/
class LOG4CPLUS_EXPORT FilterFactory : public BaseFactory {
public:
typedef Filter ProductType;
typedef FilterPtr ProductPtr;
FilterFactory();
virtual ~FilterFactory() = 0;
/**
* Create a "Filter" object.
*/
virtual FilterPtr createObject(const log4cplus::helpers::Properties& props) = 0;
};
/**
* This abstract class defines the "Factory" interface to
* create std::locale instances.
*/
class LOG4CPLUS_EXPORT LocaleFactory
: public BaseFactory
{
public:
typedef std::locale ProductType;
typedef std::locale ProductPtr;
LocaleFactory();
virtual ~LocaleFactory() = 0;
//! \returns std::locale instance
virtual ProductPtr createObject (
const log4cplus::helpers::Properties & props) = 0;
};
/**
* This template class is used as a "Factory Registry". Objects are
* "entered" into the registry with a "name" using the
* <code>put()</code> method. (The registry then owns the object.)
* These object can then be retrieved using the <code>get()</code>
* method.
*
* <b>Note:</b> This class is Thread-safe.
*/
template<class T>
class LOG4CPLUS_EXPORT FactoryRegistry
: public ObjectRegistryBase
{
public:
typedef T product_type;
virtual ~FactoryRegistry() {
clear();
}
// public methods
/**
* Used to enter an object into the registry. (The registry now
* owns <code>object</code>.)
*/
bool put(std::unique_ptr<T> object) {
bool putValResult = putVal(object->getTypeName(), object.get());
object.release();
return putValResult;
}
/**
* Used to retrieve an object from the registry. (The registry
* owns the returned pointer.)
*/
T* get(const log4cplus::tstring& name) const {
return static_cast<T*>(getVal(name));
}
protected:
virtual void deleteObject(void *object) const {
delete static_cast<T*>(object);
}
};
typedef FactoryRegistry<AppenderFactory> AppenderFactoryRegistry;
typedef FactoryRegistry<LayoutFactory> LayoutFactoryRegistry;
typedef FactoryRegistry<FilterFactory> FilterFactoryRegistry;
typedef FactoryRegistry<LocaleFactory> LocaleFactoryRegistry;
/**
* Returns the "singleton" <code>AppenderFactoryRegistry</code>.
*/
LOG4CPLUS_EXPORT AppenderFactoryRegistry& getAppenderFactoryRegistry();
/**
* Returns the "singleton" <code>LayoutFactoryRegistry</code>.
*/
LOG4CPLUS_EXPORT LayoutFactoryRegistry& getLayoutFactoryRegistry();
/**
* Returns the "singleton" <code>FilterFactoryRegistry</code>.
*/
LOG4CPLUS_EXPORT FilterFactoryRegistry& getFilterFactoryRegistry();
/**
* Returns the "singleton" <code>LocaleFactoryRegistry</code>.
*/
LOG4CPLUS_EXPORT LocaleFactoryRegistry& getLocaleFactoryRegistry();
template <typename ProductFactoryBase>
class LocalFactoryBase
: public ProductFactoryBase
{
public:
LocalFactoryBase (tchar const * n)
: name (n)
{ }
virtual log4cplus::tstring const & getTypeName() const
{
return name;
}
private:
log4cplus::tstring name;
};
template <typename LocalProduct, typename ProductFactoryBase>
class FactoryTempl
: public LocalFactoryBase<ProductFactoryBase>
{
public:
typedef typename ProductFactoryBase::ProductPtr ProductPtr;
FactoryTempl (tchar const * n)
: LocalFactoryBase<ProductFactoryBase> (n)
{ }
virtual ProductPtr createObject (helpers::Properties const & props)
{
return ProductPtr (new LocalProduct (props));
}
};
#define LOG4CPLUS_REG_PRODUCT(reg, productprefix, productname, productns, productfact) \
reg.put ( \
std::unique_ptr<productfact> ( \
new log4cplus::spi::FactoryTempl<productns productname, productfact> ( \
LOG4CPLUS_TEXT(productprefix) \
LOG4CPLUS_TEXT(#productname))))
#define LOG4CPLUS_REG_APPENDER(reg, appendername) \
LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", appendername, log4cplus::, \
log4cplus::spi::AppenderFactory)
#define LOG4CPLUS_REG_LAYOUT(reg, layoutname) \
LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::", layoutname, log4cplus::, \
log4cplus::spi::LayoutFactory)
#define LOG4CPLUS_REG_FILTER(reg, filtername) \
LOG4CPLUS_REG_PRODUCT (reg, "log4cplus::spi::", filtername, log4cplus::spi::, \
log4cplus::spi::FilterFactory)
#define LOG4CPLUS_REG_LOCALE(reg, name, factory) \
reg.put (std::unique_ptr<log4cplus::spi::LocaleFactory> ( \
new factory (name)))
} // namespace spi
}
#endif // LOG4CPLUS_SPI_FACTORY_HEADER_

View File

@@ -0,0 +1,404 @@
// -*- C++ -*-
// Module: Log4CPLUS
// File: filter.h
// Created: 5/2003
// Author: Tad E. Smith
//
//
// Copyright 1999-2017 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/** @file
* This header defines Filter and all of it's subclasses. */
#ifndef LOG4CPLUS_SPI_FILTER_HEADER_
#define LOG4CPLUS_SPI_FILTER_HEADER_
#include <log4cplus/config.hxx>
#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
#pragma once
#endif
#include <functional>
#include <log4cplus/helpers/pointer.h>
#include <log4cplus/loglevel.h>
namespace log4cplus {
namespace helpers
{
class Properties;
}
namespace spi {
enum FilterResult { DENY, /**< The log event must be dropped immediately
* without consulting with the remaining
* filters, if any, in the chain. */
NEUTRAL, /**< This filter is neutral with respect to
* the log event; the remaining filters, if
* if any, should be consulted for a final
* decision. */
ACCEPT /**< The log event must be logged immediately
* without consulting with the remaining
* filters, if any, in the chain. */
};
// Forward Declarations
class Filter;
class InternalLoggingEvent;
/**
* This method is used to filter an InternalLoggingEvent.
*
* Note: <code>filter</code> can be NULL.
*/
LOG4CPLUS_EXPORT FilterResult checkFilter(const Filter* filter,
const InternalLoggingEvent& event);
typedef helpers::SharedObjectPtr<Filter> FilterPtr;
/**
* Users should extend this class to implement customized logging
* event filtering. Note that the {@link Logger} and {@link
* Appender} classes have built-in filtering rules. It is suggested
* that you first use and understand the built-in rules before rushing
* to write your own custom filters.
*
* This abstract class assumes and also imposes that filters be
* organized in a linear chain. The {@link #decide
* decide(LoggingEvent)} method of each filter is called sequentially,
* in the order of their addition to the chain.
*
* If the value {@link #DENY} is returned, then the log event is
* dropped immediately without consulting with the remaining
* filters.
*
* If the value {@link #NEUTRAL} is returned, then the next filter
* in the chain is consulted. If there are no more filters in the
* chain, then the log event is logged. Thus, in the presence of no
* filters, the default behaviour is to log all logging events.
*
* If the value {@link #ACCEPT} is returned, then the log
* event is logged without consulting the remaining filters.
*
* The philosophy of log4cplus filters is largely inspired from the
* Linux ipchains.
*/
class LOG4CPLUS_EXPORT Filter
: public virtual log4cplus::helpers::SharedObject
{
public:
// ctor and dtor
Filter();
virtual ~Filter();
// Methods
/**
* Appends <code>filter</code> to the end of this filter chain.
*/
void appendFilter(FilterPtr filter);
/**
* If the decision is <code>DENY</code>, then the event will be
* dropped. If the decision is <code>NEUTRAL</code>, then the next
* filter, if any, will be invoked. If the decision is ACCEPT then
* the event will be logged without consulting with other filters in
* the chain.
*
* @param event The LoggingEvent to decide upon.
* @return The decision of the filter.
*/
virtual FilterResult decide(const InternalLoggingEvent& event) const = 0;
// Data
/**
* Points to the next filter in the filter chain.
*/
FilterPtr next;
};
/**
* This filter drops all logging events.
*
* You can add this filter to the end of a filter chain to
* switch from the default "accept all unless instructed otherwise"
* filtering behaviour to a "deny all unless instructed otherwise"
* behaviour.
*/
class LOG4CPLUS_EXPORT DenyAllFilter : public Filter {
public:
DenyAllFilter ();
DenyAllFilter (const log4cplus::helpers::Properties&);
/**
* Always returns the {@link #DENY} regardless of the
* {@link InternalLoggingEvent} parameter.
*/
virtual FilterResult decide(const InternalLoggingEvent& event) const;
};
/**
* This is a very simple filter based on LogLevel matching.
*
* The filter admits two options <b>LogLevelToMatch</b> and
* <b>AcceptOnMatch</b>. If there is an exact match between the value
* of the LogLevelToMatch option and the LogLevel of the {@link
* spi::InternalLoggingEvent}, then the {@link #decide} method returns
* {@link #ACCEPT} in case the <b>AcceptOnMatch</b> option value is set
* to <code>true</code>, if it is <code>false</code> then {@link #DENY}
* is returned. If there is no match, {@link #NEUTRAL} is returned.
*/
class LOG4CPLUS_EXPORT LogLevelMatchFilter : public Filter {
public:
LogLevelMatchFilter();
LogLevelMatchFilter(const log4cplus::helpers::Properties& p);
/**
* Return the decision of this filter.
*
* Returns {@link #NEUTRAL} if the <b>LogLevelToMatch</b>
* option is not set or if there is no match. Otherwise, if
* there is a match, then the returned decision is {@link #ACCEPT}
* if the <b>AcceptOnMatch</b> property is set to <code>true</code>.
* The returned decision is {@link #DENY} if the <b>AcceptOnMatch</b>
* property is set to <code>false</code>.
*/
virtual FilterResult decide(const InternalLoggingEvent& event) const;
private:
// Methods
LOG4CPLUS_PRIVATE void init();
// Data
/** Do we return ACCEPT when a match occurs. Default is <code>true</code>. */
bool acceptOnMatch;
LogLevel logLevelToMatch;
};
/**
* This is a very simple filter based on LogLevel matching, which can be
* used to reject messages with LogLevels outside a certain range.
*
* The filter admits three options <b>LogLevelMin</b>, <b>LogLevelMax</b>
* and <b>AcceptOnMatch</b>.
*
* If the LogLevel of the Logging event is not between Min and Max
* (inclusive), then {@link #DENY} is returned.
*
* If the Logging event LogLevel is within the specified range, then if
* <b>AcceptOnMatch</b> is true, {@link #ACCEPT} is returned, and if
* <b>AcceptOnMatch</b> is false, {@link #NEUTRAL} is returned.
*
* If <code>LogLevelMin</code> is not defined, then there is no
* minimum acceptable LogLevel (ie a LogLevel is never rejected for
* being too "low"/unimportant). If <code>LogLevelMax</code> is not
* defined, then there is no maximum acceptable LogLevel (ie a
* LogLevel is never rejected for beeing too "high"/important).
*
* Refer to the {@link
* Appender#setThreshold setThreshold} method
* available to <code>all</code> appenders for a more convenient way to
* filter out events by LogLevel.
*/
class LOG4CPLUS_EXPORT LogLevelRangeFilter : public Filter {
public:
// ctors
LogLevelRangeFilter();
LogLevelRangeFilter(const log4cplus::helpers::Properties& p);
/**
* Return the decision of this filter.
*/
virtual FilterResult decide(const InternalLoggingEvent& event) const;
private:
// Methods
LOG4CPLUS_PRIVATE void init();
// Data
/** Do we return ACCEPT when a match occurs. Default is <code>true</code>. */
bool acceptOnMatch;
LogLevel logLevelMin;
LogLevel logLevelMax;
};
/**
* This is a very simple filter based on string matching.
*
* The filter admits two options <b>StringToMatch</b> and
* <b>AcceptOnMatch</b>. If there is a match between the value of the
* StringToMatch option and the message of the Logging event,
* then the {@link #decide} method returns {@link #ACCEPT} if
* the <b>AcceptOnMatch</b> option value is true, if it is false then
* {@link #DENY} is returned. If there is no match, {@link #NEUTRAL}
* is returned.
*/
class LOG4CPLUS_EXPORT StringMatchFilter : public Filter {
public:
// ctors
StringMatchFilter();
StringMatchFilter(const log4cplus::helpers::Properties& p);
/**
* Returns {@link #NEUTRAL} is there is no string match.
*/
virtual FilterResult decide(const InternalLoggingEvent& event) const;
private:
// Methods
LOG4CPLUS_PRIVATE void init();
// Data
/** Do we return ACCEPT when a match occurs. Default is <code>true</code>. */
bool acceptOnMatch;
log4cplus::tstring stringToMatch;
};
/**
* This filter allows using `std::function<FilterResult(const
* InternalLoggingEvent &)>`.
*/
class LOG4CPLUS_EXPORT FunctionFilter
: public Filter
{
public:
typedef std::function<FilterResult (const InternalLoggingEvent &)>
Function;
FunctionFilter (Function);
/**
* Returns result returned by `function`.
*/
virtual FilterResult decide(const InternalLoggingEvent&) const;
private:
Function function;
};
/**
* This is a simple filter based on the string returned by event.getNDC().
*
* The filter admits three options <b>NeutralOnEmpty</b>, <b>NDCToMatch</b>
* and <b>AcceptOnMatch</b>.
*
* If <code>NeutralOnEmpty</code> is true and <code>NDCToMatch</code> is empty
* then {@link #NEUTRAL} is returned.
*
* If <code>NeutralOnEmpty</code> is true and the value returned by event.getNDC() is empty
* then {@link #NEUTRAL} is returned.
*
* If the string returned by event.getNDC() matches <code>NDCToMatch</code>, then if
* <b>AcceptOnMatch</b> is true, {@link #ACCEPT} is returned, and if
* <b>AcceptOnMatch</b> is false, {@link #DENY} is returned.
*
* If the string returned by event.getNDC() does not match <code>NDCToMatch</code>, then if
* <b>AcceptOnMatch</b> is true, {@link #DENY} is returned, and if
* <b>AcceptOnMatch</b> is false, {@link #ACCEPT} is returned.
*
*/
class LOG4CPLUS_EXPORT NDCMatchFilter : public Filter
{
public:
// ctors
NDCMatchFilter();
NDCMatchFilter(const log4cplus::helpers::Properties& p);
/**
* Returns {@link #NEUTRAL} is there is no string match.
*/
virtual FilterResult decide(const InternalLoggingEvent& event) const;
private:
// Methods
LOG4CPLUS_PRIVATE void init();
// Data
/** Do we return ACCEPT when a match occurs. Default is <code>true</code>. */
bool acceptOnMatch;
/** return NEUTRAL if event.getNDC() is empty or ndcToMatch is empty. Default is <code>true</code>. */
bool neutralOnEmpty;
log4cplus::tstring ndcToMatch;
};
/**
* This is a simple filter based on the key/value pair stored in MDC.
*
* The filter admits four options <b>NeutralOnEmpty</b>, <b>MDCKeyToMatch</b>
* <b>MDCValueToMatch</b> and <b>AcceptOnMatch</b>.
*
* If <code>NeutralOnEmpty</code> is true and <code>MDCKeyToMatch</code> or <code>MDCValueToMatch</code>
* is empty then {@link #NEUTRAL} is returned.
*
* If <code>NeutralOnEmpty</code> is true and the string returned by event.getMDC(MDCKeyToMatch) is empty
* then {@link #NEUTRAL} is returned.
*
* If the string returned by event.getMDC(MDCKeyToMatch) matches <code>MDCValueToMatch</code>, then if
* <b>AcceptOnMatch</b> is true, {@link #ACCEPT} is returned, and if
* <b>AcceptOnMatch</b> is false, {@link #DENY} is returned.
*
* If the string returned by event.getMDC(MDCKeyToMatch) does not match <code>MDCValueToMatch</code>, then if
* <b>AcceptOnMatch</b> is true, {@link #DENY} is returned, and if
* <b>AcceptOnMatch</b> is false, {@link #ACCEPT} is returned.
*
*/
class LOG4CPLUS_EXPORT MDCMatchFilter : public Filter
{
public:
// ctors
MDCMatchFilter();
MDCMatchFilter(const log4cplus::helpers::Properties& p);
/**
* Returns {@link #NEUTRAL} is there is no string match.
*/
virtual FilterResult decide(const InternalLoggingEvent& event) const;
private:
// Methods
LOG4CPLUS_PRIVATE void init();
// Data
/** Do we return ACCEPT when a match occurs. Default is <code>true</code>. */
bool acceptOnMatch;
/** return NEUTRAL if mdcKeyToMatch is empty or event::getMDC(mdcKeyValue) is empty or mdcValueToMatch is empty. Default is <code>true</code>. */
bool neutralOnEmpty;
/** The MDC key to retrieve **/
log4cplus::tstring mdcKeyToMatch;
/** the MDC value to match **/
log4cplus::tstring mdcValueToMatch;
};
} // end namespace spi
} // end namespace log4cplus
#endif /* LOG4CPLUS_SPI_FILTER_HEADER_ */

View File

@@ -0,0 +1,65 @@
// -*- C++ -*-
// Module: Log4CPLUS
// File: loggerfactory.h
// Created: 6/2001
// Author: Tad E. Smith
//
//
// Copyright 2001-2017 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/** @file */
#ifndef LOG4CPLUS_SPI_LOGGER_FACTORY_HEADER
#define LOG4CPLUS_SPI_LOGGER_FACTORY_HEADER
#include <log4cplus/config.hxx>
#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
#pragma once
#endif
#include <log4cplus/tstring.h>
namespace log4cplus {
// Forward Declarations
class Logger;
class Hierarchy;
namespace spi {
class LoggerImpl;
/**
* Implement this interface to create new instances of Logger or
* a sub-class of Logger.
*/
class LOG4CPLUS_EXPORT LoggerFactory {
public:
/**
* Creates a new <code>Logger</code> object.
*/
virtual Logger makeNewLoggerInstance(const log4cplus::tstring& name,
Hierarchy& h) = 0;
virtual ~LoggerFactory() = 0;
protected:
virtual LoggerImpl * makeNewLoggerImplInstance(
const log4cplus::tstring& name, Hierarchy& h) = 0;
};
} // end namespace spi
} // end namespace log4cplus
#endif // LOG4CPLUS_SPI_LOGGER_FACTORY_HEADER

View File

@@ -0,0 +1,216 @@
// -*- C++ -*-
// Module: Log4CPLUS
// File: loggerimpl.h
// Created: 6/2001
// Author: Tad E. Smith
//
//
// Copyright 2001-2017 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/** @file */
#ifndef LOG4CPLUS_SPI_LOGGER_HEADER_
#define LOG4CPLUS_SPI_LOGGER_HEADER_
#include <log4cplus/config.hxx>
#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
#pragma once
#endif
#include <log4cplus/tstring.h>
#include <log4cplus/helpers/appenderattachableimpl.h>
#include <log4cplus/helpers/pointer.h>
#include <log4cplus/spi/loggerfactory.h>
#include <memory>
#include <vector>
namespace log4cplus {
class DefaultLoggerFactory;
namespace spi {
/**
* This is the central class in the log4cplus package. One of the
* distintive features of log4cplus are hierarchical loggers and their
* evaluation.
*/
class LOG4CPLUS_EXPORT LoggerImpl
: public virtual log4cplus::helpers::SharedObject,
public log4cplus::helpers::AppenderAttachableImpl
{
public:
typedef helpers::SharedObjectPtr<LoggerImpl> SharedLoggerImplPtr;
// Methods
/**
* Call the appenders in the hierrachy starting at
* <code>this</code>. If no appenders could be found, emit a
* warning.
*
* This method calls all the appenders inherited from the
* hierarchy circumventing any evaluation of whether to log or not
* to log the particular log request.
*
* @param event The event to log.
*/
virtual void callAppenders(const InternalLoggingEvent& event);
/**
* Close all attached appenders implementing the AppenderAttachable
* interface.
*/
virtual void closeNestedAppenders();
/**
* Check whether this logger is enabled for a given LogLevel passed
* as parameter.
*
* @return boolean True if this logger is enabled for <code>ll</code>.
*/
virtual bool isEnabledFor(LogLevel ll) const;
/**
* This generic form is intended to be used by wrappers.
*/
virtual void log(LogLevel ll, const log4cplus::tstring& message,
const char* file=nullptr, int line=-1,
const char* function=nullptr);
virtual void log(spi::InternalLoggingEvent const &);
/**
* Starting from this logger, search the logger hierarchy for a
* "set" LogLevel and return it. Otherwise, return the LogLevel of the
* root logger.
*
* The Logger class is designed so that this method executes as
* quickly as possible.
*/
virtual LogLevel getChainedLogLevel() const;
/**
* Returns the assigned LogLevel, if any, for this Logger.
*
* @return LogLevel - the assigned LogLevel.
*/
LogLevel getLogLevel() const { return this->ll; }
/**
* Set the LogLevel of this Logger.
*/
void setLogLevel(LogLevel _ll) { this->ll = _ll; }
/**
* Return the the {@link Hierarchy} where this <code>Logger</code>
* instance is attached.
*/
virtual Hierarchy& getHierarchy() const;
/**
* Return the logger name.
*/
log4cplus::tstring const & getName() const { return name; }
/**
* Get the additivity flag for this Logger instance.
*/
bool getAdditivity() const;
/**
* Set the additivity flag for this Logger instance.
*/
void setAdditivity(bool additive);
virtual ~LoggerImpl();
protected:
// Ctors
/**
* This constructor created a new <code>Logger</code> instance and
* sets its name.
*
* It is intended to be used by sub-classes only. You should not
* create loggers directly.
*
* @param name The name of the logger.
* @param h Hierarchy
*/
LoggerImpl(const log4cplus::tstring& name, Hierarchy& h);
// Methods
/**
* This method creates a new logging event and logs the event
* without further checks.
*/
virtual void forcedLog(LogLevel ll,
const log4cplus::tstring& message,
const char* file,
int line,
const char* function);
virtual void forcedLog(spi::InternalLoggingEvent const & ev);
// Data
/** The name of this logger */
log4cplus::tstring name;
/**
* The assigned LogLevel of this logger.
*/
LogLevel ll;
/**
* The parent of this logger. All loggers have at least one
* ancestor which is the root logger.
*/
SharedLoggerImplPtr parent;
/**
* Additivity is set to true by default, that is children inherit
* the appenders of their ancestors by default. If this variable is
* set to <code>false</code> then the appenders found in the
* ancestors of this logger are not used. However, the children
* of this logger will inherit its appenders, unless the children
* have their additivity flag set to <code>false</code> too. See
* the user manual for more details.
*/
bool additive;
private:
// Data
/** Loggers need to know what Hierarchy they are in. */
Hierarchy& hierarchy;
// Disallow copying of instances of this class
LoggerImpl(const LoggerImpl&) = delete;
LoggerImpl& operator=(const LoggerImpl&) = delete;
// Friends
friend class log4cplus::Logger;
friend class log4cplus::DefaultLoggerFactory;
friend class log4cplus::Hierarchy;
};
typedef LoggerImpl::SharedLoggerImplPtr SharedLoggerImplPtr;
} // end namespace spi
} // end namespace log4cplus
#endif // LOG4CPLUS_SPI_LOGGER_HEADER_

View File

@@ -0,0 +1,239 @@
// -*- C++ -*-
// Module: Log4CPLUS
// File: loggingevent.h
// Created: 6/2001
// Author: Tad E. Smith
//
//
// Copyright 2001-2017 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/** @file */
#ifndef LOG4CPLUS_SPI_INTERNAL_LOGGING_EVENT_HEADER_
#define LOG4CPLUS_SPI_INTERNAL_LOGGING_EVENT_HEADER_
#include <log4cplus/config.hxx>
#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
#pragma once
#endif
#include <memory>
#include <log4cplus/loglevel.h>
#include <log4cplus/ndc.h>
#include <log4cplus/mdc.h>
#include <log4cplus/tstring.h>
#include <log4cplus/helpers/timehelper.h>
#include <log4cplus/thread/threads.h>
namespace log4cplus {
namespace spi {
/**
* The internal representation of logging events. When an affirmative
* decision is made to log then a <code>InternalLoggingEvent</code>
* instance is created. This instance is passed around to the
* different log4cplus components.
*
* This class is of concern to those wishing to extend log4cplus.
*/
class LOG4CPLUS_EXPORT InternalLoggingEvent {
public:
// Ctors
/**
* Instantiate a LoggingEvent from the supplied parameters.
*
* @param logger The logger of this event.
* @param loglevel The LogLevel of this event.
* @param message The message of this event.
* @param filename Name of file where this event has occurred,
* can be NULL.
* @param line Line number in file specified by
* the <code>filename</code> parameter.
* @param function Name of function that is logging this event.
*/
InternalLoggingEvent(const log4cplus::tstring& logger,
LogLevel loglevel, const log4cplus::tstring& message,
const char* filename, int line, const char * function = nullptr);
InternalLoggingEvent(const log4cplus::tstring& logger,
LogLevel loglevel, const log4cplus::tstring& ndc,
MappedDiagnosticContextMap const & mdc,
const log4cplus::tstring& message,
const log4cplus::tstring& thread,
log4cplus::helpers::Time time, const log4cplus::tstring& file,
int line, const log4cplus::tstring & function
= log4cplus::tstring ()) LOG4CPLUS_ATTRIBUTE_DEPRECATED;
InternalLoggingEvent(const log4cplus::tstring& logger,
LogLevel loglevel, const log4cplus::tstring& ndc,
MappedDiagnosticContextMap const & mdc,
const log4cplus::tstring& message,
const log4cplus::tstring& thread,
const log4cplus::tstring& thread2,
log4cplus::helpers::Time time, const log4cplus::tstring& file,
int line, const log4cplus::tstring & function
= log4cplus::tstring ());
InternalLoggingEvent ();
InternalLoggingEvent(
const log4cplus::spi::InternalLoggingEvent& rhs);
virtual ~InternalLoggingEvent();
void setLoggingEvent (const log4cplus::tstring & logger,
LogLevel ll, const log4cplus::tstring & message,
const char * filename, int line,
const char * function = nullptr);
void setFunction (char const * func);
void setFunction (log4cplus::tstring const &);
// public virtual methods
/** The application supplied message of logging event. */
virtual const log4cplus::tstring& getMessage() const;
/** Returns the 'type' of InternalLoggingEvent. Derived classes
* should override this method. (NOTE: Values <= 1000 are
* reserved for log4cplus and should not be used.)
*/
virtual unsigned int getType() const;
/** Returns a copy of this object. Derived classes
* should override this method.
*/
virtual std::unique_ptr<InternalLoggingEvent> clone() const;
// public methods
/** The logger of the logging event. It is set by
* the LoggingEvent constructor.
*/
const log4cplus::tstring& getLoggerName() const
{
return loggerName;
}
/** LogLevel of logging event. */
LogLevel getLogLevel() const
{
return ll;
}
/** The nested diagnostic context (NDC) of logging event. */
const log4cplus::tstring& getNDC() const
{
if (!ndcCached)
{
ndc = log4cplus::getNDC().get();
ndcCached = true;
}
return ndc;
}
MappedDiagnosticContextMap const & getMDCCopy () const
{
if (!mdcCached)
{
mdc = log4cplus::getMDC().getContext ();
mdcCached = true;
}
return mdc;
}
tstring const & getMDC (tstring const & key) const;
/** The name of thread in which this logging event was generated. */
const log4cplus::tstring& getThread() const
{
if (! threadCached)
{
thread = thread::getCurrentThreadName ();
threadCached = true;
}
return thread;
}
//! The alternative name of thread in which this logging event
//! was generated.
const log4cplus::tstring& getThread2() const
{
if (! thread2Cached)
{
thread2 = thread::getCurrentThreadName2 ();
thread2Cached = true;
}
return thread2;
}
/** Time stamp when the event was created. */
const log4cplus::helpers::Time& getTimestamp() const
{
return timestamp;
}
/** The is the file where this log statement was written */
const log4cplus::tstring& getFile() const
{
return file;
}
/** The is the line where this log statement was written */
int getLine() const { return line; }
log4cplus::tstring const & getFunction () const
{
return function;
}
void gatherThreadSpecificData () const;
void swap (InternalLoggingEvent &);
// public operators
log4cplus::spi::InternalLoggingEvent&
operator=(const log4cplus::spi::InternalLoggingEvent& rhs);
// static methods
static unsigned int getDefaultType();
protected:
// Data
log4cplus::tstring message;
log4cplus::tstring loggerName;
LogLevel ll;
mutable log4cplus::tstring ndc;
mutable MappedDiagnosticContextMap mdc;
mutable log4cplus::tstring thread;
mutable log4cplus::tstring thread2;
log4cplus::helpers::Time timestamp;
log4cplus::tstring file;
log4cplus::tstring function;
int line;
/** Indicates whether or not the Threadname has been retrieved. */
mutable bool threadCached;
mutable bool thread2Cached;
/** Indicates whether or not the NDC has been retrieved. */
mutable bool ndcCached;
/** Indicates whether or not the MDC has been retrieved. */
mutable bool mdcCached;
};
} // end namespace spi
} // end namespace log4cplus
#endif // LOG4CPLUS_SPI_INTERNAL_LOGGING_EVENT_HEADER_

View File

@@ -0,0 +1,113 @@
// -*- C++ -*-
// Module: Log4CPLUS
// File: objectregistry.h
// Created: 3/2003
// Author: Tad E. Smith
//
//
// Copyright 2003-2017 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/** @file */
#ifndef LOG4CPLUS_SPI_OBJECT_REGISTRY_HEADER_
#define LOG4CPLUS_SPI_OBJECT_REGISTRY_HEADER_
#include <log4cplus/config.hxx>
#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
#pragma once
#endif
#include <log4cplus/tstring.h>
#include <log4cplus/thread/syncprims.h>
#include <map>
#include <memory>
#include <vector>
namespace log4cplus {
namespace spi {
/**
* This is the base class used to implement the functionality required
* by the ObjectRegistry template class.
*/
class LOG4CPLUS_EXPORT ObjectRegistryBase {
public:
// public methods
/**
* Tests to see whether or not an object is bound in the
* registry as <code>name</code>.
*/
bool exists(const log4cplus::tstring& name) const;
/**
* Returns the names of all registered objects.
*/
std::vector<log4cplus::tstring> getAllNames() const;
//! This function is internal implementation detail.
//! It is related to work-around needed for initialization when
//! using C++11 threads and mutexes.
void _enableLocking (bool);
protected:
// Ctor and Dtor
ObjectRegistryBase();
virtual ~ObjectRegistryBase();
// protected methods
/**
* Used to enter an object into the registry. (The registry now
* owns <code>object</code>.)
*/
bool putVal(const log4cplus::tstring& name, void* object);
/**
* Used to retrieve an object from the registry. (The registry
* owns the returned pointer.)
*/
void* getVal(const log4cplus::tstring& name) const;
/**
* Deletes <code>object</code>.
*/
virtual void deleteObject(void *object) const = 0;
/**
* Deletes all objects from this registry.
*/
virtual void clear();
// Types
typedef std::map<log4cplus::tstring, void*> ObjectMap;
// Data
thread::Mutex mutex;
ObjectMap data;
private:
ObjectRegistryBase (ObjectRegistryBase const &);
ObjectRegistryBase & operator = (ObjectRegistryBase const &);
bool volatile locking;
};
}
}
#endif // LOG4CPLUS_SPI_OBJECT_REGISTRY_HEADER_

View File

@@ -0,0 +1,75 @@
// -*- C++ -*-
// Module: Log4CPLUS
// File: rootlogger.h
// Created: 6/2001
// Author: Tad E. Smith
//
//
// Copyright 2001-2017 Tad E. Smith
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/** @file */
#ifndef LOG4CPLUS_SPI_ROOT_LOGGER_HEADER_
#define LOG4CPLUS_SPI_ROOT_LOGGER_HEADER_
#include <log4cplus/config.hxx>
#if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE)
#pragma once
#endif
#include <log4cplus/spi/loggerimpl.h>
namespace log4cplus {
namespace spi {
/**
* RootLogger sits at the top of the logger hierachy. It is a
* regular logger except that it provides several guarantees.
*
* First, it cannot be assigned a <code>NOT_SET_LOG_LEVEL</code>
* LogLevel. Second, since root logger cannot have a parent, the
* getChainedLogLevel method always returns the value of the
* ll field without walking the hierarchy.
*/
class LOG4CPLUS_EXPORT RootLogger : public LoggerImpl {
public:
// Ctors
/**
* The root logger names itself as "root". However, the root
* logger cannot be retrieved by name.
*/
RootLogger(Hierarchy& h, LogLevel ll);
// Methods
/**
* Return the assigned LogLevel value without walking the logger
* hierarchy.
*/
virtual LogLevel getChainedLogLevel() const;
/**
* Setting a NOT_SET_LOG_LEVEL value to the LogLevel of the root logger
* may have catastrophic results. We prevent this here.
*/
void setLogLevel(LogLevel);
};
} // end namespace spi
} // end namespace log4cplus
#endif // LOG4CPLUS_SPI_ROOT_LOGGER_HEADER_