-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathLoggerService.h
141 lines (109 loc) · 5.42 KB
/
LoggerService.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "stdafx.h"
#pragma warning(push)
#pragma warning(disable: 4995) // disable so that memcpy can be used
#include <fstream>
#include <sstream>
#include <queue>
#pragma warning(pop)
#ifndef PLATFORM_UNIX
#include <functional>
#include <thread>
#endif
#include "../InstrumentationEngine.Api/InstrumentationEngine.h"
#include "LoggerSink.h"
#include "../Common.Headers/InitOnce.h"
using namespace CommonLib;
// Fixes the error "implicit instantiation of undefined template 'std::hash<LoggingFlags>'"
// when building gnu with Clang 3.5 by supplying a full template specialization.
namespace std
{
template<>
class hash<LoggingFlags> {
public:
std::size_t operator()(LoggingFlags const& key) const noexcept {
return key;
}
};
}
namespace MicrosoftInstrumentationEngine
{
class CLoggerService
{
private:
static const int LogEntryMaxSize = 4096;
static const LoggingFlags LoggingFlags_All = (LoggingFlags)(LoggingFlags_Errors | LoggingFlags_Trace | LoggingFlags_InstrumentationResults);
static constexpr const WCHAR* LogLevelEnvironmentVariableName = _T("MicrosoftInstrumentationEngine_LogLevel");
private:
// Used to protect all fields
CCriticalSection m_cs;
// The flags initially determined by the service or set via the SetLoggingFlags method.
LoggingFlags m_defaultFlags;
// The effective set of flags (flags that are in actual use) as determined by querying
// each of the logger sinks. This is updated each time a logger sink dependency is changed
// e.g. calling SetLoggingFlags, SetLoggingHost, and SetLogToDebugPort.
//
// We're using atomic here to avoid a critical section in GetLoggingFlags.
std::atomic<LoggingFlags> m_effectiveFlags;
// This is the cumulative LoggingFlags for all InstrumentationMethods
LoggingFlags m_instrumentationMethodFlags;
// This Map contains as keys each of the LoggingFlags and for each key the value is the set of
// InstrumentationMethods that support the LoggingFlags.
//
// For Ubuntu builds we are currently using Clang 3.5 which fails compiling using sets and unordered_sets with
// the following error: "error: debug information for auto is not yet supported". Once we update
// the version of Clang, consider refactoring this vector of GUIDs to a set.
std::unordered_map<LoggingFlags, std::vector<GUID>> m_loggingFlagsToInstrumentationMethodsMap;
// This function type will get invoked when the effective flags gets updated.
std::function<void(const LoggingFlags&)> m_LoggingFlagsCallback;
bool m_fLogToDebugPort;
CInitOnce m_initialize;
ATL::CComPtr<IProfilerManagerLoggingHost> m_pLoggingHost;
std::vector<std::shared_ptr<ILoggerSink>> m_allSinks;
std::vector<std::shared_ptr<ILoggerSink>> m_errorSinks;
std::vector<std::shared_ptr<ILoggerSink>> m_messageSinks;
std::vector<std::shared_ptr<ILoggerSink>> m_dumpSinks;
public:
CLoggerService();
CLoggerService(const CLoggerService&) = delete;
~CLoggerService();
public:
CLoggerService& operator=(const CLoggerService&) = delete;
private:
static LoggingFlags ExtractLoggingFlag(
_In_ LPCWSTR wszRequestedFlagNames,
_In_ LPCWSTR wszSingleTestFlagName,
_In_ LoggingFlags singleTestFlag
);
HRESULT InitializeCore();
HRESULT RecalculateLoggingFlags();
// Updates the logging flags for the specific InstrumentationMethod classId
HRESULT UpdateInstrumentationMethodFlags(_In_ GUID classId, _In_ LoggingFlags loggingFlags);
// For the given loggingLevel, updates the Vector with adding/removing the classId based on the loggingFlags
HRESULT UpdateInstrumentationMethodFlagsInternal(_In_ GUID classId, _In_ LoggingFlags loggingFlags, _In_ LoggingFlags loggingLevel);
public:
bool AllowLogEntry(_In_ LoggingFlags flags);
static LoggingFlags ExtractLoggingFlags(_In_ LPCWSTR wszRequestedFlagNames);
HRESULT Initialize(_In_ std::function<void(const LoggingFlags&)> loggingFlagsCallback = nullptr);
void LogMessage(_In_ LPCWSTR wszMessage, _In_ va_list argptr);
void LogMessage(_In_ LPCWSTR wszMessage, ...);
void LogError(_In_ LPCWSTR wszMessage, _In_ va_list argptr);
void LogError(_In_ LPCWSTR wszError, ...);
void LogDumpMessage(_In_ LPCWSTR wszMessage, _In_ va_list argptr);
void LogDumpMessage(_In_ LPCWSTR wszMessage, ...);
HRESULT GetLoggingHost(_Out_ IProfilerManagerLoggingHost** ppLoggingHost);
HRESULT SetLoggingHost(_In_opt_ IProfilerManagerLoggingHost* pLoggingHost);
bool GetLogToDebugPort();
void SetLogToDebugPort(_In_ bool enable);
HRESULT GetLoggingFlags(_Out_ LoggingFlags* pLoggingFlags);
HRESULT SetLoggingFlags(_In_ LoggingFlags loggingFlags);
HRESULT UpdateInstrumentationMethodLoggingFlags(_In_ GUID classId, _In_ LoggingFlags loggingFlags);
HRESULT SetLogFilePath(_In_ LPCWSTR wszLogFilePath);
HRESULT SetLogFileLevel(_In_ LoggingFlags fileLogFlags);
HRESULT Shutdown();
protected:
virtual HRESULT CreateSinks(std::vector<std::shared_ptr<ILoggerSink>>& sinks);
};
}