1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | //----------------------------------------------------------------------------- |
5 | // PerfLog.h |
6 | |
7 | // Internal interface for logging perfromance data. Currently, two types of logging |
8 | // formats are supported, Pretty print for stdout and perf automation friendly |
9 | // format. |
10 | // The logging code is compiled in for retail builds but logs are generated only if |
11 | // PERF_OUTPUT environment variable is set. (This can be changed to a registry entry |
12 | // if we want perf logs on CE or other platforms that don't supprt env vars.)) |
13 | //----------------------------------------------------------------------------- |
14 | |
15 | #include "contract.h" |
16 | |
17 | #ifndef _PERFLOG_H_ |
18 | #define _PERFLOG_H_ |
19 | |
20 | #if !defined(_WIN64) && !defined(DACCESS_COMPILE) |
21 | #define ENABLE_PERF_LOG |
22 | #else |
23 | #undef ENABLE_PERF_LOG |
24 | #endif |
25 | |
26 | // Also disable Perf logging code if there's a explicite define to do so in SOURCES |
27 | // file or another hdr file. This provides one point where all perf log related baggage |
28 | // can be avoided in the build. |
29 | #if defined(DISABLE_PERF_LOG) |
30 | #undef ENABLE_PERF_LOG |
31 | #endif |
32 | |
33 | |
34 | //----------------------------------------------------------------------------- |
35 | // PERFLOG is the public interface that should be used from EE source to log perf data. |
36 | // If |
37 | #if !defined (ENABLE_PERF_LOG) |
38 | #define PERFLOG(x) |
39 | #else |
40 | #define PERFLOG(x) do {if (PerfLog::PerfLoggingEnabled()) PerfLog::Log x;} while (0) |
41 | #endif |
42 | |
43 | //============================================================================= |
44 | // ALL THE PERF LOG CODE IS COMPILED ONLY IF THE ENABLE_PERF_LOG WAS DEFINED. |
45 | #if defined (ENABLE_PERF_LOG) |
46 | //============================================================================= |
47 | //----------------------------------------------------------------------------- |
48 | // Static allocation of logging related memory, avoid dynamic allocation to |
49 | // skew perf numbers. |
50 | #define PRINT_STR_LEN 256 // Temp work space |
51 | #define MAX_CHARS_UNIT 20 |
52 | #define MAX_CHARS_DIRECTION 6 |
53 | |
54 | //----------------------------------------------------------------------------- |
55 | // ENUM of units for all kinds of perf data the we might get. Grow this as needed. |
56 | // **keep in sync *** with the array of strings defined in PerfLog.cpp |
57 | typedef enum |
58 | { |
59 | COUNT = 0, |
60 | SECONDS, |
61 | BYTES, |
62 | KBYTES, |
63 | KBYTES_PER_SEC, |
64 | CYCLES, |
65 | MAX_UNITS_OF_MEASURE |
66 | } UnitOfMeasure; |
67 | |
68 | //----------------------------------------------------------------------------- |
69 | // Widechar strings representing the above units. *** Keep in sync *** with the |
70 | // array defined in PerfLog.cpp |
71 | extern const wchar_t * const wszUnitOfMeasureDescr[MAX_UNITS_OF_MEASURE]; |
72 | |
73 | //----------------------------------------------------------------------------- |
74 | // Widechar strings representing the "direction" property of above units. |
75 | // *** Keep in sync *** with the array defined in PerfLog.cpp |
76 | // "Direction" property is false if an increase in the value of the counter indicates |
77 | // a degrade. |
78 | // "Direction" property is true if an increase in the value of the counter indicates |
79 | // an improvement. |
80 | extern const wchar_t * const wszIDirection[MAX_UNITS_OF_MEASURE]; |
81 | |
82 | //----------------------------------------------------------------------------- |
83 | // Namespace for perf log. Don't create perf log objects (private ctor). |
84 | class PerfLog |
85 | { |
86 | public: |
87 | |
88 | // Called during EEStartup |
89 | static void PerfLogInitialize(); |
90 | |
91 | // Called during EEShutdown |
92 | static void PerfLogDone(); |
93 | |
94 | // Perf logging is enabled if the env var PERF_LOG is set. |
95 | static int PerfLoggingEnabled () { LIMITED_METHOD_CONTRACT; return m_fLogPerfData; } |
96 | |
97 | // Perf automation format is desired. |
98 | static bool PerfAutomationFormat () { LIMITED_METHOD_CONTRACT; return m_perfAutomationFormat; } |
99 | |
100 | // CSV format is desired. |
101 | static bool CommaSeparatedFormat () { LIMITED_METHOD_CONTRACT; return m_commaSeparatedFormat; } |
102 | |
103 | // Overloaded member functions to print different data types. Grow as needed. |
104 | // wszName is the name of thet perf counter, val is the perf counter value, |
105 | static void Log(__in_z wchar_t const *wszName, UINT val, UnitOfMeasure unit, __in_opt const wchar_t *wszDescr = 0); |
106 | static void Log(__in_z wchar_t const *wszName, UINT64 val, UnitOfMeasure unit, __in_opt const wchar_t *wszDescr = 0); |
107 | static void Log(__in_z wchar_t const *wszName, double val, UnitOfMeasure unit, __in_opt const wchar_t *wszDescr = 0); |
108 | |
109 | private: |
110 | PerfLog(); |
111 | ~PerfLog(); |
112 | |
113 | // Helper routine to hide some details of the perf automation |
114 | static void OutToPerfFile(__in_z const wchar_t *wszName, UnitOfMeasure unit, __in_opt const wchar_t *wszDescr = 0); |
115 | |
116 | // Helper routine to hide some details of output to stdout |
117 | static void OutToStdout(__in_z const wchar_t *wszName, UnitOfMeasure unit, __in_opt const wchar_t *wszDescr = 0); |
118 | |
119 | // Perf log initialized ? |
120 | static bool m_perfLogInit; |
121 | |
122 | // Output in perf automation format ? |
123 | static bool m_perfAutomationFormat; |
124 | |
125 | // Output in csv format ? |
126 | static bool m_commaSeparatedFormat; |
127 | |
128 | // Temp storage to convert wide char to multibyte for file IO. |
129 | static wchar_t m_wszOutStr_1[PRINT_STR_LEN]; |
130 | static DWORD m_dwWriteByte; |
131 | |
132 | // State of the env var PERF_OUTPUT |
133 | static int m_fLogPerfData; |
134 | |
135 | // Open handle of the file which is used by the perf auotmation. (Currently |
136 | // its at C:\PerfData.data |
137 | static HANDLE m_hPerfLogFileHandle; |
138 | }; |
139 | |
140 | #endif // ENABLE_PERF_LOG |
141 | |
142 | #endif //_PERFLOG_H_ |
143 | |