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
57typedef 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
71extern 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.
80extern const wchar_t * const wszIDirection[MAX_UNITS_OF_MEASURE];
81
82//-----------------------------------------------------------------------------
83// Namespace for perf log. Don't create perf log objects (private ctor).
84class PerfLog
85{
86public:
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
109private:
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