| 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 | |