Skip to content

Commit 038a008

Browse files
committed
setLevel function now available for all loggers (and the manager).
1 parent 51adfb1 commit 038a008

File tree

10 files changed

+158
-54
lines changed

10 files changed

+158
-54
lines changed

docs/htmlsrc/guides/logging/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ <h2>Logger Types</h2>
7777
<li><ci dox="ci::log::LoggerFileRotating">LoggerFileRotating</ci> directs log messages to a specified file. The name of that file is evaluated at the first logging call after application startup, and re-evaluated at the first logging call after midnight.</li>
7878
<li>
7979
<ci dox="ci::log::LoggerBreakpoint">LoggerBreakpoint</ci> doesn't actually log messages, but triggers a breakpoint on log events above a specified threshold. <code>triggerLevel</code> defines the minimum logging level that will break execution.
80-
<br>The trigger level can be controlled by calling <ci dox="ci::log::LoggerBreakpoint::setTriggerLevel">LoggerBreakpoint::setTriggerLevel()</ci>.
80+
<br>The trigger level can be controlled by calling <ci dox="ci::log::LoggerBreakpoint::setLevel">LoggerBreakpoint::setLevel()</ci>.
8181
</li>
8282
<li><ci dox="ci::log::LoggerSystem">LoggerSystem</ci> will write log messages to the platform specific system log. This currently means the system log on OS X <code>/var/log/system.log</code> and the Event Log on Windows with MSW applications. WinRT system logging is still being developed.</li>
8383
</ul>
8484
<h3>LoggerSystem Notes</h3>
8585
<h4>Minimum System Logging Level</h4>
8686
<p>
87-
The minimum system logging level can be controlled by calling <ci dox="ci::log::LoggerSystem::setLoggingLevel">LoggerSystem::setLoggingLevel()</ci>. This level can be controlled independently of the Cinder minimum logging level, but the system logging level can never be lower than the Cinder minimum logging level. For more information on this, see the section on <a href="#optimization">Compile Time Settings & Optimization.</a>
87+
The minimum system logging level can be controlled by calling <ci dox="ci::log::LoggerSystem::setLevel">LoggerSystem::setLevel()</ci>. This level can be controlled independently of the preprocessor Cinder minimum logging level, but the system logging level can never be lower than the Cinder minimum logging level. For more information on this, see the section on <a href="#optimization">Compile Time Settings & Optimization.</a>
8888
</p>
8989
<h4>OS X Specific Notes</h4>
9090
<p>
@@ -143,7 +143,7 @@ <h3>Usage</h3>
143143
<p>
144144
<b>Example 3: Getting an active logger:</b><br>
145145
<pre><code class="language-cpp">// gets the active LoggerSystem and sets the minimum level to LEVEL_ERROR
146-
log::manager()->getLoggers&lt;log::LoggerSystem&gt;()[0]->setLoggingLevel( log::LEVEL_ERROR );</code></pre>
146+
log::manager()->getLoggers&lt;log::LoggerSystem&gt;()[0]->setLevel( log::LEVEL_ERROR );</code></pre>
147147
</p>
148148
</section>
149149

include/cinder/Log.h

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@
3535
#include <vector>
3636
#include <memory>
3737
#include <mutex>
38+
#include <functional>
39+
40+
// CI_MIN_LOG_LEVEL is designed so that if you set it to 7 : nothing logs, 6 : only fatal, 5 : fatal + error, ..., 1 : everything
41+
42+
#if ! defined( CI_MIN_LOG_LEVEL )
43+
#if ! defined( NDEBUG )
44+
#define CI_MIN_LOG_LEVEL 0 // debug mode default is LEVEL_VERBOSE
45+
#else
46+
#define CI_MIN_LOG_LEVEL 2 // release mode default is LEVEL_INFO
47+
#endif
48+
#endif
3849

3950
namespace cinder { namespace log {
4051

@@ -86,13 +97,17 @@ class CI_API Logger : private Noncopyable {
8697
void setTimestampEnabled( bool enable = true ) { mTimeStampEnabled = enable; }
8798
bool isTimestampEnabled() const { return mTimeStampEnabled; }
8899

89-
protected:
90-
Logger() : mTimeStampEnabled( false ) {}
100+
void setLevel( Level level ) { mLevel = level; }
101+
Level getLevel() const { return mLevel; }
91102

103+
protected:
104+
Logger( Level level = static_cast<Level>( CI_MIN_LOG_LEVEL ) ) : mLevel( level ), mTimeStampEnabled( false ) {}
105+
92106
void writeDefault( std::ostream &stream, const Metadata &meta, const std::string &text );
93107

108+
Level mLevel;
94109
private:
95-
bool mTimeStampEnabled;
110+
bool mTimeStampEnabled;
96111
};
97112

98113
typedef std::shared_ptr<Logger> LoggerRef;
@@ -134,13 +149,17 @@ class CI_API LoggerFileRotating : public LoggerFile {
134149

135150
//! Creates a rotating log file that will rotate when the first logging event occurs after midnight.
136151
//! \p formatStr will be passed to strftime to determine the file name.
137-
LoggerFileRotating( const fs::path &folder, const std::string &formatStr, bool appendToExisting = true );
152+
LoggerFileRotating( const fs::path &folder, const std::string &formatStr, bool appendToExisting = true, std::function<void( const fs::path& )> fileChangeFn = nullptr );
138153

139154
virtual ~LoggerFileRotating() { }
140155

141156
void write( const Metadata &meta, const std::string &text ) override;
142-
157+
143158
protected:
159+
void setFilePath( const fs::path& filepath );
160+
161+
std::function<void( const fs::path& )> mFileChangeFn;
162+
144163
fs::path mFolderPath;
145164
std::string mDailyFormatStr;
146165
int mYearDay;
@@ -150,16 +169,10 @@ class CI_API LoggerFileRotating : public LoggerFile {
150169
class CI_API LoggerBreakpoint : public Logger {
151170
public:
152171
LoggerBreakpoint( Level triggerLevel = LEVEL_ERROR )
153-
: mTriggerLevel( triggerLevel )
172+
: Logger{ triggerLevel }
154173
{}
155174

156175
void write( const Metadata &meta, const std::string &text ) override;
157-
158-
void setTriggerLevel( Level triggerLevel ) { mTriggerLevel = triggerLevel; }
159-
Level getTriggerLevel() const { return mTriggerLevel; }
160-
161-
private:
162-
Level mTriggerLevel;
163176
};
164177

165178
//! LoggerSystem rovides 'system' logging support. Uses syslog on platforms that have it, on MSW uses Windows Event Logging.
@@ -170,12 +183,8 @@ class CI_API LoggerSystem : public Logger {
170183
virtual ~LoggerSystem();
171184

172185
void write( const Metadata &meta, const std::string &text ) override;
173-
//! Sets the minimum logging level that will trigger a system log.
174-
//! \note Setting \p minLevel below CI_MIN_LOG_LEVEL is pointless; minLevel will act like CI_MIN_LOG_LEVEL.
175-
void setLoggingLevel( Level minLevel ) { mMinLevel = minLevel; }
176-
186+
177187
protected:
178-
Level mMinLevel;
179188
#if defined( CINDER_COCOA ) || defined( CINDER_LINUX )
180189
class ImplSysLog;
181190
std::unique_ptr<ImplSysLog> mImpl;
@@ -215,6 +224,8 @@ class CI_API LogManager {
215224
std::vector<LoggerRef> getAllLoggers();
216225
//! Returns the mutex used for thread safe logging.
217226
std::mutex& getMutex() const { return mMutex; }
227+
//! Set the logging level for all active loggers.
228+
void setLevel( Level level );
218229

219230
void write( const Metadata &meta, const std::string &text );
220231

@@ -329,15 +340,6 @@ std::vector<std::shared_ptr<LoggerT>> LogManager::getLoggers()
329340

330341
#define CINDER_LOG_STREAM( level, stream ) ::cinder::log::Entry( level, ::cinder::log::Location( CINDER_CURRENT_FUNCTION, __FILE__, __LINE__ ) ) << stream
331342

332-
// CI_MIN_LOG_LEVEL is designed so that if you set it to 7 : nothing logs, 6 : only fatal, 5 : fatal + error, ..., 1 : everything
333-
334-
#if ! defined( CI_MIN_LOG_LEVEL )
335-
#if ! defined( NDEBUG )
336-
#define CI_MIN_LOG_LEVEL 0 // debug mode default is LEVEL_VERBOSE
337-
#else
338-
#define CI_MIN_LOG_LEVEL 2 // release mode default is LEVEL_INFO
339-
#endif
340-
#endif
341343

342344
#if( CI_MIN_LOG_LEVEL <= 0 )
343345
#define CI_LOG_V( stream ) CINDER_LOG_STREAM( ::cinder::log::LEVEL_VERBOSE, stream )

include/cinder/Utilities.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ CI_API fs::path expandPath( const fs::path &path );
4242
CI_API fs::path getHomeDirectory();
4343
//! Returns a path to the user's documents directory.
4444
CI_API fs::path getDocumentsDirectory();
45+
//! Removes all files beyond maxFileCount, keeping only the most recently modified ones.
46+
CI_API void limitDirectoryFileCount( const fs::path& directoryPath, size_t maxFileCount );
4547

4648
//! Launches a path in a web browser
4749
CI_API void launchWebBrowser( const Url &url );

samples/Logging/src/LoggingApp.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "cinder/app/App.h"
22
#include "cinder/app/RendererGl.h"
33
#include "cinder/gl/gl.h"
4+
#include "cinder/Utilities.h"
45

56
using namespace ci;
67
using namespace ci::app;
@@ -17,6 +18,7 @@ class LoggingApp : public App {
1718

1819
public:
1920
void setup() override;
21+
void keyDown( KeyEvent event ) override;
2022
void mouseDown( MouseEvent event ) override;
2123
void update() override;
2224
void draw() override;
@@ -42,21 +44,39 @@ void LoggingApp::setup()
4244
enableSysLogging();
4345
}
4446

47+
void LoggingApp::keyDown( KeyEvent event )
48+
{
49+
//! Change log trigger levels for all active loggers with keys 0-5.
50+
if( event.isShiftDown() && event.isAltDown() ) {
51+
switch( event.getCode() ) {
52+
case KeyEvent::KEY_0: log::manager()->setLevel( log::LEVEL_VERBOSE ); break;
53+
case KeyEvent::KEY_1: log::manager()->setLevel( log::LEVEL_DEBUG ); break;
54+
case KeyEvent::KEY_2: log::manager()->setLevel( log::LEVEL_INFO ); break;
55+
case KeyEvent::KEY_3: log::manager()->setLevel( log::LEVEL_WARNING ); break;
56+
case KeyEvent::KEY_4: log::manager()->setLevel( log::LEVEL_ERROR ); break;
57+
case KeyEvent::KEY_5: log::manager()->setLevel( log::LEVEL_FATAL ); break;
58+
default: break;
59+
}
60+
}
61+
}
62+
4563
void LoggingApp::enableFileLogging()
4664
{
4765
//! This call will append log messages to the file `cinder.log` in the folder `/tmp/logging`.
4866
//! If the folder path `/tmp/logging` does not exist, it will be created for you.
4967

50-
log::makeLogger<log::LoggerFile>( "/tmp/logging/cinder.log", true );
68+
log::makeLogger<log::LoggerFile>( app::getAppPath() / "cinder.log", true );
5169
}
5270

5371
void LoggingApp::enableFileLoggingRotating()
5472
{
5573
//! This call will append log messages to a rotating file in the folder `/tmp/logging`.
5674
//! The filename `cinder.%Y.%m.%d.log` will be evaluated by strftime. For the example
5775
//! below, the filename could evaluate to `cinder.2015.08.28.log`.
58-
59-
log::makeLogger<log::LoggerFileRotating>( "/tmp/logging", "cinder.%Y.%m.%d.log" );
76+
log::makeLogger<log::LoggerFileRotating>( app::getAppPath() / "logs", "cinder.%Y.%m.%d.log", true, []( const fs::path& path ) {
77+
// Only preserve logs from the last 10 days
78+
ci::limitDirectoryFileCount( path.parent_path(), 10 );
79+
} );
6080
}
6181

6282
void LoggingApp::enableSysLogging()
@@ -67,8 +87,8 @@ void LoggingApp::enableSysLogging()
6787
auto sysLogger = log::makeLogger<log::LoggerSystem>();
6888

6989
//! This call will set the system logging level independent of the file/console logging level.
70-
//! The system logging level can not be lower than the file/console logging.
71-
sysLogger->setLoggingLevel( log::LEVEL_WARNING );
90+
//! The system logging level can not be lower than the preprocessor-defined level.
91+
sysLogger->setLevel( log::LEVEL_WARNING );
7292
}
7393

7494
void LoggingApp::mouseDown( MouseEvent event )

samples/Logging/vc2019/Logging.sln

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,40 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Logging", "Logging.vcxproj"
66
EndProject
77
Global
88
GlobalSection(SolutionConfigurationPlatforms) = preSolution
9+
Debug_ANGLE|Win32 = Debug_ANGLE|Win32
10+
Debug_ANGLE|x64 = Debug_ANGLE|x64
11+
Debug_Shared|Win32 = Debug_Shared|Win32
12+
Debug_Shared|x64 = Debug_Shared|x64
913
Debug|Win32 = Debug|Win32
1014
Debug|x64 = Debug|x64
15+
Release_ANGLE|Win32 = Release_ANGLE|Win32
16+
Release_ANGLE|x64 = Release_ANGLE|x64
17+
Release_Shared|Win32 = Release_Shared|Win32
18+
Release_Shared|x64 = Release_Shared|x64
1119
Release|Win32 = Release|Win32
1220
Release|x64 = Release|x64
1321
EndGlobalSection
1422
GlobalSection(ProjectConfigurationPlatforms) = postSolution
23+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug_ANGLE|Win32.ActiveCfg = Debug|Win32
24+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug_ANGLE|Win32.Build.0 = Debug|Win32
25+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug_ANGLE|x64.ActiveCfg = Debug|x64
26+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug_ANGLE|x64.Build.0 = Debug|x64
27+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug_Shared|Win32.ActiveCfg = Debug|Win32
28+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug_Shared|Win32.Build.0 = Debug|Win32
29+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug_Shared|x64.ActiveCfg = Debug|x64
30+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug_Shared|x64.Build.0 = Debug|x64
1531
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug|Win32.ActiveCfg = Debug|Win32
1632
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug|Win32.Build.0 = Debug|Win32
1733
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug|x64.ActiveCfg = Debug|x64
1834
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Debug|x64.Build.0 = Debug|x64
35+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Release_ANGLE|Win32.ActiveCfg = Release|Win32
36+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Release_ANGLE|Win32.Build.0 = Release|Win32
37+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Release_ANGLE|x64.ActiveCfg = Release|x64
38+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Release_ANGLE|x64.Build.0 = Release|x64
39+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Release_Shared|Win32.ActiveCfg = Release|Win32
40+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Release_Shared|Win32.Build.0 = Release|Win32
41+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Release_Shared|x64.ActiveCfg = Release|x64
42+
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Release_Shared|x64.Build.0 = Release|x64
1943
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Release|Win32.ActiveCfg = Release|Win32
2044
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Release|Win32.Build.0 = Release|Win32
2145
{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}.Release|x64.ActiveCfg = Release|x64
@@ -24,4 +48,7 @@ Global
2448
GlobalSection(SolutionProperties) = preSolution
2549
HideSolutionNode = FALSE
2650
EndGlobalSection
51+
GlobalSection(ExtensibilityGlobals) = postSolution
52+
SolutionGuid = {57121B3D-8E9D-4FC5-A025-D7C7D2CDACA8}
53+
EndGlobalSection
2754
EndGlobal

samples/Logging/vc2019/Logging.vcxproj

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,33 @@
2222
<ProjectGuid>{1FDCFE3E-16AD-43F0-AF04-F281F40C1419}</ProjectGuid>
2323
<RootNamespace>Logging</RootNamespace>
2424
<Keyword>Win32Proj</Keyword>
25+
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
2526
</PropertyGroup>
2627
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
2728
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
2829
<ConfigurationType>Application</ConfigurationType>
2930
<UseDebugLibraries>false</UseDebugLibraries>
30-
<PlatformToolset>v140</PlatformToolset>
31+
<PlatformToolset>v142</PlatformToolset>
3132
<CharacterSet>Unicode</CharacterSet>
3233
<WholeProgramOptimization>true</WholeProgramOptimization>
3334
</PropertyGroup>
3435
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
3536
<ConfigurationType>Application</ConfigurationType>
3637
<UseDebugLibraries>false</UseDebugLibraries>
37-
<PlatformToolset>v140</PlatformToolset>
38+
<PlatformToolset>v142</PlatformToolset>
3839
<CharacterSet>Unicode</CharacterSet>
3940
<WholeProgramOptimization>true</WholeProgramOptimization>
4041
</PropertyGroup>
4142
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
4243
<ConfigurationType>Application</ConfigurationType>
4344
<UseDebugLibraries>true</UseDebugLibraries>
44-
<PlatformToolset>v140</PlatformToolset>
45+
<PlatformToolset>v142</PlatformToolset>
4546
<CharacterSet>Unicode</CharacterSet>
4647
</PropertyGroup>
4748
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
4849
<ConfigurationType>Application</ConfigurationType>
4950
<UseDebugLibraries>true</UseDebugLibraries>
50-
<PlatformToolset>v140</PlatformToolset>
51+
<PlatformToolset>v142</PlatformToolset>
5152
<CharacterSet>Unicode</CharacterSet>
5253
</PropertyGroup>
5354
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -88,6 +89,7 @@
8889
<WarningLevel>Level3</WarningLevel>
8990
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
9091
<MultiProcessorCompilation>true</MultiProcessorCompilation>
92+
<LanguageStandard>stdcpp17</LanguageStandard>
9193
</ClCompile>
9294
<ResourceCompile>
9395
<AdditionalIncludeDirectories>"..\..\..\include";..\include</AdditionalIncludeDirectories>
@@ -114,6 +116,7 @@
114116
<WarningLevel>Level3</WarningLevel>
115117
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
116118
<MultiProcessorCompilation>true</MultiProcessorCompilation>
119+
<LanguageStandard>stdcpp17</LanguageStandard>
117120
</ClCompile>
118121
<ResourceCompile>
119122
<AdditionalIncludeDirectories>"..\..\..\include";..\include</AdditionalIncludeDirectories>
@@ -137,6 +140,7 @@
137140
<WarningLevel>Level3</WarningLevel>
138141
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
139142
<MultiProcessorCompilation>true</MultiProcessorCompilation>
143+
<LanguageStandard>stdcpp17</LanguageStandard>
140144
</ClCompile>
141145
<ProjectReference>
142146
<LinkLibraryDependencies>true</LinkLibraryDependencies>
@@ -166,6 +170,7 @@
166170
<WarningLevel>Level3</WarningLevel>
167171
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
168172
<MultiProcessorCompilation>true</MultiProcessorCompilation>
173+
<LanguageStandard>stdcpp17</LanguageStandard>
169174
</ClCompile>
170175
<ProjectReference>
171176
<LinkLibraryDependencies>true</LinkLibraryDependencies>

0 commit comments

Comments
 (0)