1 #include <stdio.h>
2 #include <stdarg.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <time.h>
6
7 #define INTEL_NO_MACRO_BODY
8 #define INTEL_ITTNOTIFY_API_PRIVATE
9 #include "ittnotify.h"
10 #include "ittnotify_config.h"
11
12 #define LOG_BUFFER_MAX_SIZE 256
13
14 static const char* env_log_dir = "INTEL_LIBITTNOTIFY_LOG_DIR";
15 static const char* log_level_str[] = {"INFO", "WARN", "ERROR", "FATAL_ERROR"};
16
17 enum {
18 LOG_LVL_INFO,
19 LOG_LVL_WARN,
20 LOG_LVL_ERROR,
21 LOG_LVL_FATAL
22 };
23
24 static struct ref_collector_logger {
25 char* file_name;
26 uint8_t init_state;
27 } g_ref_collector_logger = {NULL, 0};
28
log_file_name_generate()29 char* log_file_name_generate()
30 {
31 time_t time_now = time(NULL);
32 struct tm* time_info = localtime(&time_now);
33 char* log_file_name = malloc(sizeof(char) * (LOG_BUFFER_MAX_SIZE/2));
34
35 sprintf(log_file_name,"libittnotify_refcol_%d%d%d%d%d%d.log",
36 time_info->tm_year+1900, time_info->tm_mon+1, time_info->tm_mday,
37 time_info->tm_hour, time_info->tm_min, time_info->tm_sec);
38
39 return log_file_name;
40 }
41
ref_col_init()42 void ref_col_init()
43 {
44 if (!g_ref_collector_logger.init_state)
45 {
46 static char file_name_buffer[LOG_BUFFER_MAX_SIZE*2];
47 char* log_dir = getenv(env_log_dir);
48 char* log_file = log_file_name_generate();
49
50 if (log_dir != NULL)
51 {
52 #ifdef _WIN32
53 sprintf(file_name_buffer,"%s\\%s", log_dir, log_file);
54 #else
55 sprintf(file_name_buffer,"%s/%s", log_dir, log_file);
56 #endif
57 }
58 else
59 {
60 #ifdef _WIN32
61 char* temp_dir = getenv("TEMP");
62 if (temp_dir != NULL)
63 {
64 sprintf(file_name_buffer,"%s\\%s", temp_dir, log_file);
65 }
66 #else
67 sprintf(file_name_buffer,"/tmp/%s", log_file);
68 #endif
69 }
70
71 g_ref_collector_logger.file_name = file_name_buffer;
72 g_ref_collector_logger.init_state = 1;
73 }
74 }
75
fill_func_ptr_per_lib(__itt_global * p)76 static void fill_func_ptr_per_lib(__itt_global* p)
77 {
78 __itt_api_info* api_list = (__itt_api_info*)p->api_list_ptr;
79
80 for (int i = 0; api_list[i].name != NULL; i++)
81 {
82 *(api_list[i].func_ptr) = (void*)__itt_get_proc(p->lib, api_list[i].name);
83 if (*(api_list[i].func_ptr) == NULL)
84 {
85 *(api_list[i].func_ptr) = api_list[i].null_func;
86 }
87 }
88 }
89
__itt_api_init(__itt_global * p,__itt_group_id init_groups)90 ITT_EXTERN_C void ITTAPI __itt_api_init(__itt_global* p, __itt_group_id init_groups)
91 {
92 if (p != NULL)
93 {
94 fill_func_ptr_per_lib(p);
95 ref_col_init();
96 }
97 else
98 {
99 printf("ERROR: Failed to initialize dynamic library\n");
100 }
101 }
102
log_func_call(uint8_t log_level,const char * function_name,const char * message_format,...)103 void log_func_call(uint8_t log_level, const char* function_name, const char* message_format, ...)
104 {
105 if (g_ref_collector_logger.init_state)
106 {
107 FILE * pLogFile = NULL;
108 char log_buffer[LOG_BUFFER_MAX_SIZE];
109 uint32_t result_len = 0;
110 va_list message_args;
111
112 result_len += sprintf(log_buffer, "[%s] %s(...) - ", log_level_str[log_level] ,function_name);
113 va_start(message_args, message_format);
114 vsnprintf(log_buffer + result_len, LOG_BUFFER_MAX_SIZE - result_len, message_format, message_args);
115
116 pLogFile = fopen(g_ref_collector_logger.file_name, "a");
117 if (!pLogFile)
118 {
119 printf("ERROR: Cannot open file: %s\n", g_ref_collector_logger.file_name);
120 return;
121 }
122 fprintf(pLogFile, "%s\n", log_buffer);
123 fclose(pLogFile);
124 }
125 else
126 {
127 return;
128 }
129 }
130
131 #define LOG_FUNC_CALL_INFO(...) log_func_call(LOG_LVL_INFO, __FUNCTION__, __VA_ARGS__)
132 #define LOG_FUNC_CALL_WARN(...) log_func_call(LOG_LVL_WARN, __FUNCTION__, __VA_ARGS__)
133 #define LOG_FUNC_CALL_ERROR(...) log_func_call(LOG_LVL_ERROR, __FUNCTION__, __VA_ARGS__)
134 #define LOG_FUNC_CALL_FATAL(...) log_func_call(LOG_LVL_FATAL, __FUNCTION__, __VA_ARGS__)
135
136 /* ------------------------------------------------------------------------------ */
137 /* The code below is a reference implementation of the ITT API dynamic collector. */
138 /* This implementation is designed to log ITTAPI functions calls.*/
139 /* ------------------------------------------------------------------------------ */
140
get_metadata_elements(size_t size,__itt_metadata_type type,void * metadata)141 char* get_metadata_elements(size_t size, __itt_metadata_type type, void* metadata)
142 {
143 char* metadata_str = malloc(sizeof(char) * LOG_BUFFER_MAX_SIZE);
144 *metadata_str = '\0';
145
146 switch (type)
147 {
148 case __itt_metadata_u64:
149 for (uint16_t i = 0; i < size; i++)
150 sprintf(metadata_str, "%s%llu;", metadata_str, ((uint64_t*)metadata)[i]);
151 break;
152 case __itt_metadata_s64:
153 for (uint16_t i = 0; i < size; i++)
154 sprintf(metadata_str, "%s%lld;", metadata_str, ((int64_t*)metadata)[i]);
155 break;
156 case __itt_metadata_u32:
157 for (uint16_t i = 0; i < size; i++)
158 sprintf(metadata_str, "%s%lu;", metadata_str, ((uint32_t*)metadata)[i]);
159 break;
160 case __itt_metadata_s32:
161 for (uint16_t i = 0; i < size; i++)
162 sprintf(metadata_str, "%s%ld;", metadata_str, ((int32_t*)metadata)[i]);
163 break;
164 case __itt_metadata_u16:
165 for (uint16_t i = 0; i < size; i++)
166 sprintf(metadata_str, "%s%u;", metadata_str, ((uint16_t*)metadata)[i]);
167 break;
168 case __itt_metadata_s16:
169 for (uint16_t i = 0; i < size; i++)
170 sprintf(metadata_str, "%s%d;", metadata_str, ((int16_t*)metadata)[i]);
171 break;
172 case __itt_metadata_float:
173 for (uint16_t i = 0; i < size; i++)
174 sprintf(metadata_str, "%s%f;", metadata_str, ((float*)metadata)[i]);
175 break;
176 case __itt_metadata_double:
177 for (uint16_t i = 0; i < size; i++)
178 sprintf(metadata_str, "%s%lf;", metadata_str, ((double*)metadata)[i]);
179 break;
180 default:
181 printf("ERROR: Unknow metadata type\n");
182 }
183
184 return metadata_str;
185 }
186
__itt_pause(void)187 ITT_EXTERN_C void ITTAPI __itt_pause(void)
188 {
189 LOG_FUNC_CALL_INFO("function call");
190 }
191
__itt_resume(void)192 ITT_EXTERN_C void ITTAPI __itt_resume(void)
193 {
194 LOG_FUNC_CALL_INFO("function call");
195 }
196
__itt_detach(void)197 ITT_EXTERN_C void ITTAPI __itt_detach(void)
198 {
199 LOG_FUNC_CALL_INFO("function call");
200 }
201
__itt_frame_begin_v3(const __itt_domain * domain,__itt_id * id)202 ITT_EXTERN_C void ITTAPI __itt_frame_begin_v3(const __itt_domain *domain, __itt_id *id)
203 {
204 if (domain != NULL)
205 {
206 LOG_FUNC_CALL_INFO("functions args: domain_name=%s", domain->nameA);
207 }
208 else
209 {
210 LOG_FUNC_CALL_WARN("Incorrect function call");
211 }
212 }
213
__itt_frame_end_v3(const __itt_domain * domain,__itt_id * id)214 ITT_EXTERN_C void ITTAPI __itt_frame_end_v3(const __itt_domain *domain, __itt_id *id)
215 {
216 if (domain != NULL)
217 {
218 LOG_FUNC_CALL_INFO("functions args: domain_name=%s", domain->nameA);
219 }
220 else
221 {
222 LOG_FUNC_CALL_WARN("Incorrect function call");
223 }
224 }
225
__itt_frame_submit_v3(const __itt_domain * domain,__itt_id * id,__itt_timestamp begin,__itt_timestamp end)226 ITT_EXTERN_C void ITTAPI __itt_frame_submit_v3(const __itt_domain *domain, __itt_id *id,
227 __itt_timestamp begin, __itt_timestamp end)
228 {
229 if (domain != NULL)
230 {
231 LOG_FUNC_CALL_INFO("functions args: domain_name=%s, time_begin=%lu, time_end=%llu",
232 domain->nameA, (uint64_t*)id, begin, end);
233 }
234 else
235 {
236 LOG_FUNC_CALL_WARN("Incorrect function call");
237 }
238 }
239
__itt_task_begin(const __itt_domain * domain,__itt_id taskid,__itt_id parentid,__itt_string_handle * name)240 ITT_EXTERN_C void ITTAPI __itt_task_begin(
241 const __itt_domain *domain, __itt_id taskid, __itt_id parentid, __itt_string_handle *name)
242 {
243 if (domain != NULL && name != NULL)
244 {
245 LOG_FUNC_CALL_INFO("functions args: domain_name=%s handle_name=%s", domain->nameA, name->strA);
246 }
247 else
248 {
249 LOG_FUNC_CALL_WARN("Incorrect function call");
250 }
251 }
252
__itt_task_end(const __itt_domain * domain)253 ITT_EXTERN_C void ITTAPI __itt_task_end(const __itt_domain *domain)
254 {
255 if (domain != NULL)
256 {
257 LOG_FUNC_CALL_INFO("functions args: domain_name=%s", domain->nameA);
258 }
259 else
260 {
261 LOG_FUNC_CALL_WARN("Incorrect function call");
262 }
263 }
264
__itt_metadata_add(const __itt_domain * domain,__itt_id id,__itt_string_handle * key,__itt_metadata_type type,size_t count,void * data)265 ITT_EXTERN_C void __itt_metadata_add(const __itt_domain *domain, __itt_id id,
266 __itt_string_handle *key, __itt_metadata_type type, size_t count, void *data)
267 {
268 if (domain != NULL && count != 0)
269 {
270 LOG_FUNC_CALL_INFO("functions args: domain_name=%s metadata_size=%lu metadata[]=%s",
271 domain->nameA, count, get_metadata_elements(count, type, data));
272 }
273 else
274 {
275 LOG_FUNC_CALL_WARN("Incorrect function call");
276 }
277 }
278