Coverage Report

Created: 2026-06-15 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/logging-log4cxx/src/main/include/log4cxx/asyncappender.h
Line
Count
Source
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
#ifndef _LOG4CXX_ASYNC_APPENDER_H
19
#define _LOG4CXX_ASYNC_APPENDER_H
20
21
#include <log4cxx/appenderskeleton.h>
22
#include <log4cxx/helpers/appenderattachableimpl.h>
23
#include <log4cxx/spi/loggingevent.h>
24
25
namespace LOG4CXX_NS
26
{
27
LOG4CXX_LIST_DEF(LoggingEventList, spi::LoggingEventPtr);
28
29
/**
30
The AsyncAppender decouples logging event creation from output
31
by processing log events asynchronously.
32
33
The AsyncAppender stores the logging event in a bounded buffer
34
and then returns control to the application.
35
A separate thread forwards events to the attached appender(s).
36
37
An AsyncAppender is used when you configure a logger to be asynchronous.
38
These AsyncAppender(s) use [the default values](@ref log4cxx::AsyncAppender::setOption) for all options
39
and they cannot be changed using configuration file entries.
40
For more control over the AsyncAppender options,
41
use <b>appender-ref</b> element in the logger configuration instead. 
42
43
<b>Important notes:</b>
44
- Your application must call LogManager::shutdown when it exits
45
to prevent undefined behaviour when using this appender.
46
- Runtime configuration of options requires an XML configuration file
47
(see the example below).
48
49
This appender is useful when outputting to a slow event sink,
50
for example, unbuffered output to a file,
51
a remote SMTP server or a database.
52
Note that configuring a FileAppender to use [buffered output](@ref log4cxx::FileAppender::setOption)
53
usually results in lower overhead than
54
attaching the FileAppender to an AsyncAppender
55
as the inter-thread communication overhead
56
can exceed the time to add a message to a buffer.
57
58
You can attach multiple appenders to an AsyncAppender by:
59
- calling AsyncAppender::addAppender repeatedly when progammatically configuring Log4cxx.
60
- adding multiple <b>appender-ref</b> elements
61
to the <b>appender class="AsyncAppender"</b> element
62
when using runtime configuration.
63
64
Here is a sample configuration file:
65
\include async-example.xml
66
67
### Configurable properties
68
69
\anchor BlockingProperty When the application produces logging events faster
70
than the background thread is able to process,
71
the bounded buffer can become full.
72
In this situation AsyncAppender will either
73
block until the bounded buffer has a free slot or
74
discard the event.
75
The [Blocking property](@ref AsyncAppender::setOption) controls which behaviour is used.
76
When events are discarded,
77
the logged output will indicate this
78
with a log message prefixed with <i>Discarded</i>.
79
The output may contain one <i>Discarded</i> message per logger name,
80
the logging event of the highest level for each logger
81
whose events have been discarded.
82
83
To determine whether the application produces logging events faster
84
than the background thread is able to process, enable [Log4cxx internal debugging](internal-debugging.html).
85
The AsyncAppender will output a histogram of queue length frequencies when closed.
86
87
See AsyncAppender::setOption for details.
88
89
*/
90
class LOG4CXX_EXPORT AsyncAppender :
91
  public virtual spi::AppenderAttachable,
92
#if LOG4CXX_ABI_VERSION <= 15
93
  public virtual AppenderSkeleton
94
#else
95
  public AppenderSkeleton
96
#endif
97
{
98
  protected:
99
    struct AsyncAppenderPriv;
100
101
  public:
102
    DECLARE_LOG4CXX_OBJECT(AsyncAppender)
103
0
    BEGIN_LOG4CXX_CAST_MAP()
104
0
    LOG4CXX_CAST_ENTRY(AsyncAppender)
105
0
    LOG4CXX_CAST_ENTRY_CHAIN(AppenderSkeleton)
106
0
    LOG4CXX_CAST_ENTRY(spi::AppenderAttachable)
107
0
    END_LOG4CXX_CAST_MAP()
108
109
    /**
110
     * Create new instance.
111
    */
112
    AsyncAppender();
113
114
    /**
115
     *  If not closed, calls AsyncAppender::close.
116
     */
117
    virtual ~AsyncAppender();
118
119
    /**
120
     * Ensure \c newAppender receives any logging event
121
     * added to this appender.
122
     *
123
     * @param newAppender appender to add, may not be null.
124
    */
125
    void addAppender(const AppenderPtr newAppender) override;
126
127
    /**
128
    * Call AppenderSkeleton#doAppendImpl without acquiring a lock.
129
    */
130
    void doAppend( LOG4CXX_APPEND_FORMAL_PARAMETERS ) override;
131
132
    /**
133
    * Add \c event to a ring buffer.
134
    * The behaviour when the ring buffer is full
135
    * is controlled by the [Blocking property](@ref BlockingProperty) value.
136
    */
137
    void append( LOG4CXX_APPEND_FORMAL_PARAMETERS ) override;
138
139
    /**
140
    Close this <code>AsyncAppender</code> by interrupting the
141
    dispatcher thread which will process all pending events before
142
    exiting.
143
    */
144
    void close() override;
145
146
    /**
147
     * Get iterator over attached appenders.
148
     * @return list of all attached appenders.
149
    */
150
    AppenderList getAllAppenders() const override;
151
152
    /**
153
     * Get appender by name.
154
     *
155
     * @param name name, may not be null.
156
     * @return matching appender or null.
157
    */
158
    AppenderPtr getAppender(const LogString& name) const override;
159
160
    /**
161
     * The current value of the (unused) <b>LocationInfo</b> option.
162
    */
163
    bool getLocationInfo() const;
164
    /**
165
    * Determines if specified appender is attached.
166
    * @param appender appender.
167
    * @return true if attached.
168
    */
169
    bool isAttached(const AppenderPtr appender) const override;
170
171
    /** Return false
172
    */
173
    bool requiresLayout() const override;
174
175
    /**
176
     * Removes and closes all attached appenders.
177
    */
178
    void removeAllAppenders() override;
179
180
    /**
181
     * Removes an appender.
182
     * @param appender appender to remove.
183
    */
184
    void removeAppender(const AppenderPtr appender) override;
185
    /**
186
    * Remove appender by name.
187
    * @param name name.
188
    */
189
    void removeAppender(const LogString& name) override;
190
191
    /**
192
     * Replace \c oldAppender  with \c newAppender.
193
     * @return true if oldAppender was replaced with newAppender.
194
     */
195
    bool replaceAppender(const AppenderPtr& oldAppender, const AppenderPtr& newAppender) LOG4CXX_16_VIRTUAL_SPECIFIER;
196
197
    /**
198
     * Replace any previously added appenders with \c newList.
199
     */
200
    void replaceAppenders(const AppenderList& newList) LOG4CXX_16_VIRTUAL_SPECIFIER;
201
202
    /**
203
    * The <b>LocationInfo</b> attribute is provided for compatibility
204
    * with log4j and has no effect on the log output.
205
    * @param flag new value.
206
    */
207
    void setLocationInfo(bool flag);
208
209
    /**
210
    * Use \c newSize (a non-negative integer value) for
211
    * the number of [logging events](@ref spi::LoggingEvent) the ring buffer can hold.
212
    * The ring buffer size cannot be changed once the appender has received an event.
213
    * */
214
    void setBufferSize(int newSize);
215
216
    /**
217
     * Gets the current buffer size.
218
     * @return the current value of the <b>BufferSize</b> option.
219
    */
220
    int getBufferSize() const;
221
222
    /**
223
     * Use \c newValue for whether appender should block the calling thread
224
     * if there is no space in the ring buffer.
225
     *
226
     * @param newValue true if appender should wait until space is available in the ring buffer.
227
     */
228
    void setBlocking(bool newValue);
229
230
    /**
231
     * Gets whether appender should block calling thread when ring buffer is full.
232
     * If false, messages will be counted by logger and a summary
233
     * message added after the buffered events have been appended.
234
     *
235
     * @return true if calling thread will be blocked when ring buffer is full.
236
     */
237
    bool getBlocking() const;
238
239
240
    /**
241
    \copybrief AppenderSkeleton::setOption()
242
243
    Supported options | Supported values | Default value |
244
    -------------- | ---------------- | --------------- |
245
    BufferSize | int  | 128 |
246
    Blocking | True,False | True |
247
248
    \sa AppenderSkeleton::setOption()
249
     */
250
    void setOption(const LogString& option, const LogString& value) override;
251
252
253
  private:
254
    AsyncAppender(const AsyncAppender&);
255
    AsyncAppender& operator=(const AsyncAppender&);
256
257
}; // class AsyncAppender
258
LOG4CXX_PTR_DEF(AsyncAppender);
259
}  //  namespace log4cxx
260
261
#endif//  _LOG4CXX_ASYNC_APPENDER_H
262