log_ut.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. #include "log.h"
  2. #include "context.h"
  3. #include "profile.h"
  4. #include <yql/essentials/utils/log/ut/log_parser.h>
  5. #include <library/cpp/testing/unittest/registar.h>
  6. #include <library/cpp/logger/stream.h>
  7. #include <util/datetime/base.h>
  8. #include <util/generic/yexception.h>
  9. #include <util/system/getpid.h>
  10. #include <util/string/split.h>
  11. #include <util/string/cast.h>
  12. #include <util/string/subst.h>
  13. #include <regex>
  14. using namespace NYql;
  15. using namespace NLog;
  16. Y_UNIT_TEST_SUITE(TLogTest)
  17. {
  18. Y_UNIT_TEST(Format) {
  19. TStringStream out;
  20. YqlLoggerScope logger(&out);
  21. YqlLogger().UpdateProcInfo("my_proc");
  22. TString message = "some performance info";
  23. YQL_LOG(INFO) << message;
  24. TLogRow logRow = ParseLogRow(out.Str());
  25. TDuration elapsed(logRow.Time - TInstant::Now());
  26. UNIT_ASSERT(elapsed < TDuration::MilliSeconds(5));
  27. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  28. UNIT_ASSERT_STRINGS_EQUAL(logRow.ProcName, "my_proc");
  29. UNIT_ASSERT_EQUAL(logRow.ProcId, GetPID());
  30. UNIT_ASSERT(logRow.ThreadId > 0);
  31. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  32. UNIT_ASSERT_STRINGS_EQUAL(
  33. logRow.FileName,
  34. TStringBuf(__FILE__).RNextTok(LOCSLASH_C));
  35. UNIT_ASSERT(logRow.LineNumber != 0);
  36. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, message);
  37. }
  38. Y_UNIT_TEST(Levels) {
  39. TStringStream out;
  40. YqlLoggerScope logger(&out); // default log level INFO
  41. YQL_LOG(FATAL) << "fatal message";
  42. YQL_LOG(ERROR) << "error message";
  43. YQL_LOG(WARN) << "warning message";
  44. YQL_LOG(INFO) << "info message";
  45. YQL_LOG(DEBUG) << "debug message";
  46. YQL_LOG(TRACE) << "trace message";
  47. TString fatalStr, errorStr, warnStr, infoStr, _;
  48. Split(out.Str(), '\n', fatalStr, errorStr, warnStr, infoStr, _);
  49. {
  50. TLogRow logRow = ParseLogRow(fatalStr);
  51. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::FATAL);
  52. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  53. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "fatal message");
  54. }
  55. {
  56. TLogRow logRow = ParseLogRow(errorStr);
  57. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::ERROR);
  58. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  59. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "error message");
  60. }
  61. {
  62. TLogRow logRow = ParseLogRow(warnStr);
  63. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::WARN);
  64. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  65. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "warning message");
  66. }
  67. {
  68. TLogRow logRow = ParseLogRow(infoStr);
  69. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  70. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  71. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "info message");
  72. }
  73. }
  74. Y_UNIT_TEST(Components) {
  75. TStringStream out;
  76. YqlLoggerScope logger(&out);
  77. YQL_CLOG(INFO, Default) << "default message";
  78. YQL_CLOG(INFO, Core) << "core message";
  79. YQL_CLOG(INFO, Sql) << "sql message";
  80. YQL_CLOG(INFO, ProviderCommon) << "common message";
  81. YQL_CLOG(INFO, ProviderYt) << "yt message";
  82. YQL_CLOG(INFO, ProviderKikimr) << "kikimr message";
  83. YQL_CLOG(INFO, ProviderRtmr) << "rtmr message";
  84. YQL_CLOG(INFO, Performance) << "performance message";
  85. YQL_CLOG(INFO, Perf) << "perf message";
  86. TString defaultStr, coreStr, sqlStr, commonStr, ytStr,
  87. kikimrStr, rtmrStr, performanceStr, perfStr, _;
  88. Split(out.Str(), '\n', defaultStr, coreStr, sqlStr,
  89. commonStr, ytStr,
  90. kikimrStr, rtmrStr,
  91. performanceStr, perfStr, _);
  92. {
  93. TLogRow logRow = ParseLogRow(defaultStr);
  94. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  95. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  96. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "default message");
  97. }
  98. {
  99. TLogRow logRow = ParseLogRow(coreStr);
  100. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  101. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Core);
  102. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "core message");
  103. }
  104. {
  105. TLogRow logRow = ParseLogRow(sqlStr);
  106. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  107. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Sql);
  108. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "sql message");
  109. }
  110. {
  111. TLogRow logRow = ParseLogRow(commonStr);
  112. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  113. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::ProviderCommon);
  114. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "common message");
  115. }
  116. {
  117. TLogRow logRow = ParseLogRow(ytStr);
  118. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  119. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::ProviderYt);
  120. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "yt message");
  121. }
  122. {
  123. TLogRow logRow = ParseLogRow(kikimrStr);
  124. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  125. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::ProviderKikimr);
  126. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "kikimr message");
  127. }
  128. {
  129. TLogRow logRow = ParseLogRow(rtmrStr);
  130. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  131. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::ProviderRtmr);
  132. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "rtmr message");
  133. }
  134. {
  135. TLogRow logRow = ParseLogRow(performanceStr);
  136. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  137. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Performance);
  138. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Perf);
  139. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "performance message");
  140. }
  141. {
  142. TLogRow logRow = ParseLogRow(perfStr);
  143. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  144. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Perf);
  145. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Performance);
  146. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "perf message");
  147. }
  148. }
  149. Y_UNIT_TEST(Conditional) {
  150. TStringStream out;
  151. YqlLoggerScope logger(&out);
  152. YQL_LOG_IF(INFO, true) << "default info message";
  153. YQL_LOG_IF(INFO, false) << "must not be logged";
  154. YQL_CLOG_IF(INFO, Perf, true) << "perf info message";
  155. YQL_CLOG_IF(INFO, Perf, false) << "perf info message";
  156. TString defaultStr, perfStr, _;
  157. Split(out.Str(), '\n', defaultStr, perfStr, _);
  158. {
  159. TLogRow logRow = ParseLogRow(defaultStr);
  160. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  161. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  162. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "default info message");
  163. }
  164. {
  165. TLogRow logRow = ParseLogRow(perfStr);
  166. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  167. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Perf);
  168. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "perf info message");
  169. }
  170. }
  171. Y_UNIT_TEST(Contexts) {
  172. TStringStream out;
  173. YqlLoggerScope logger(&out);
  174. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "");
  175. YQL_LOG(INFO) << "level0 - begin";
  176. {
  177. YQL_LOG_CTX_SCOPE("ctx1");
  178. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx1");
  179. YQL_LOG(INFO) << "level1 - begin";
  180. YQL_LOG_CTX_BLOCK(TStringBuf("ctx2")) {
  181. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx1/ctx2");
  182. YQL_LOG(WARN) << "level2";
  183. }
  184. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx1");
  185. YQL_LOG(INFO) << "level1 - end";
  186. }
  187. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "");
  188. YQL_LOG(INFO) << "level0 - end";
  189. TString row1Str, row2Str, row3Str, row4Str, row5Str, _;
  190. Split(out.Str(), '\n', row1Str, row2Str, row3Str, row4Str, row5Str, _);
  191. {
  192. TLogRow logRow = ParseLogRow(row1Str);
  193. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  194. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  195. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "level0 - begin");
  196. }
  197. {
  198. TLogRow logRow = ParseLogRow(row2Str);
  199. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  200. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  201. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx1} level1 - begin");
  202. }
  203. {
  204. TLogRow logRow = ParseLogRow(row3Str);
  205. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::WARN);
  206. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  207. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx1/ctx2} level2");
  208. }
  209. {
  210. TLogRow logRow = ParseLogRow(row4Str);
  211. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  212. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  213. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx1} level1 - end");
  214. }
  215. {
  216. TLogRow logRow = ParseLogRow(row5Str);
  217. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  218. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  219. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "level0 - end");
  220. }
  221. }
  222. Y_UNIT_TEST(UnknownSessionContexts) {
  223. TStringStream out;
  224. YqlLoggerScope logger(&out);
  225. {
  226. YQL_LOG_CTX_ROOT_SCOPE("ctx");
  227. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().first, "");
  228. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx");
  229. YQL_LOG(INFO) << "level0 - begin";
  230. {
  231. YQL_LOG_CTX_ROOT_SESSION_SCOPE(CurrentLogContextPath());
  232. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().first, "");
  233. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx");
  234. YQL_LOG(INFO) << "level1 - begin";
  235. YQL_LOG_CTX_BLOCK("ctx1") {
  236. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().first, "");
  237. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx/ctx1");
  238. YQL_LOG(WARN) << "level2";
  239. }
  240. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().first, "");
  241. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx");
  242. YQL_LOG(INFO) << "level1 - end";
  243. }
  244. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().first, "");
  245. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx");
  246. YQL_LOG(INFO) << "level0 - end";
  247. }
  248. TString row1Str, row2Str, row3Str, row4Str, row5Str, _;
  249. Split(out.Str(), '\n', row1Str, row2Str, row3Str, row4Str, row5Str, _);
  250. {
  251. TLogRow logRow = ParseLogRow(row1Str);
  252. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  253. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  254. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx} level0 - begin");
  255. }
  256. {
  257. TLogRow logRow = ParseLogRow(row2Str);
  258. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  259. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  260. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx} level1 - begin");
  261. }
  262. {
  263. TLogRow logRow = ParseLogRow(row3Str);
  264. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::WARN);
  265. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  266. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx/ctx1} level2");
  267. }
  268. {
  269. TLogRow logRow = ParseLogRow(row4Str);
  270. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  271. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  272. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx} level1 - end");
  273. }
  274. {
  275. TLogRow logRow = ParseLogRow(row5Str);
  276. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  277. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  278. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx} level0 - end");
  279. }
  280. }
  281. Y_UNIT_TEST(SessionContexts) {
  282. TStringStream out;
  283. YqlLoggerScope logger(&out);
  284. {
  285. YQL_LOG_CTX_ROOT_SESSION_SCOPE("sessionId", "ctx");
  286. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().first, "sessionId");
  287. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx");
  288. YQL_LOG(INFO) << "level0 - begin";
  289. {
  290. YQL_LOG_CTX_ROOT_SESSION_SCOPE(CurrentLogContextPath());
  291. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().first, "sessionId");
  292. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx");
  293. YQL_LOG(INFO) << "level1 - begin";
  294. YQL_LOG_CTX_BLOCK("ctx1") {
  295. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().first, "sessionId");
  296. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx/ctx1");
  297. YQL_LOG(WARN) << "level2";
  298. }
  299. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().first, "sessionId");
  300. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx");
  301. YQL_LOG(INFO) << "level1 - end";
  302. }
  303. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().first, "sessionId");
  304. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx");
  305. YQL_LOG(INFO) << "level0 - end";
  306. }
  307. TString row1Str, row2Str, row3Str, row4Str, row5Str, _;
  308. Split(out.Str(), '\n', row1Str, row2Str, row3Str, row4Str, row5Str, _);
  309. {
  310. TLogRow logRow = ParseLogRow(row1Str);
  311. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  312. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  313. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{sessionId/ctx} level0 - begin");
  314. }
  315. {
  316. TLogRow logRow = ParseLogRow(row2Str);
  317. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  318. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  319. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{sessionId/ctx} level1 - begin");
  320. }
  321. {
  322. TLogRow logRow = ParseLogRow(row3Str);
  323. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::WARN);
  324. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  325. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{sessionId/ctx/ctx1} level2");
  326. }
  327. {
  328. TLogRow logRow = ParseLogRow(row4Str);
  329. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  330. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  331. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{sessionId/ctx} level1 - end");
  332. }
  333. {
  334. TLogRow logRow = ParseLogRow(row5Str);
  335. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  336. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  337. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{sessionId/ctx} level0 - end");
  338. }
  339. }
  340. Y_UNIT_TEST(ThrowWithContext) {
  341. bool isThrown = false;
  342. YQL_LOG_CTX_SCOPE("first");
  343. try {
  344. YQL_LOG_CTX_SCOPE("second");
  345. YQL_LOG_CTX_THROW yexception() << "some message";
  346. } catch (const yexception& e) {
  347. isThrown = true;
  348. UNIT_ASSERT_STRINGS_EQUAL(e.AsStrBuf(), "some message");
  349. TString throwedLogCtx = ThrowedLogContextPath();
  350. TStringBuf file, line, context;
  351. TStringBuf(throwedLogCtx).Split(".cpp:", file, line);
  352. line.Split(':', line, context);
  353. TString expectedFile(__LOCATION__.File);
  354. SubstGlobal(expectedFile, LOCSLASH_C, '/');
  355. UNIT_ASSERT_STRINGS_EQUAL(TString(file)+".cpp", expectedFile);
  356. int lineNumber;
  357. UNIT_ASSERT(TryFromString<int>(line, lineNumber));
  358. UNIT_ASSERT(lineNumber > 0);
  359. UNIT_ASSERT_STRINGS_EQUAL(context, " {first/second} ");
  360. // second call without throw returns empty string
  361. throwedLogCtx = ThrowedLogContextPath();
  362. UNIT_ASSERT(throwedLogCtx.empty());
  363. }
  364. UNIT_ASSERT_C(isThrown, "exception was not thrown");
  365. }
  366. Y_UNIT_TEST(ContextOverride) {
  367. TStringStream out;
  368. YqlLoggerScope logger(&out);
  369. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "");
  370. {
  371. YQL_LOG_CTX_SCOPE("ctx1");
  372. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx1");
  373. YQL_LOG(INFO) << "level1 - begin";
  374. YQL_LOG_CTX_BLOCK(TStringBuf("ctx2")) {
  375. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx1/ctx2");
  376. YQL_LOG(WARN) << "level2 - begin";
  377. {
  378. YQL_LOG_CTX_ROOT_SCOPE("ctx3");
  379. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx3");
  380. YQL_LOG(ERROR) << "level3";
  381. }
  382. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx1/ctx2");
  383. YQL_LOG(WARN) << "level2 - end";
  384. }
  385. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "ctx1");
  386. YQL_LOG(INFO) << "level1 - end";
  387. }
  388. UNIT_ASSERT_STRINGS_EQUAL(CurrentLogContextPath().second, "");
  389. TString row1Str, row2Str, row3Str, row4Str, row5Str, _;
  390. Split(out.Str(), '\n', row1Str, row2Str, row3Str, row4Str, row5Str, _);
  391. {
  392. TLogRow logRow = ParseLogRow(row1Str);
  393. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  394. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  395. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx1} level1 - begin");
  396. }
  397. {
  398. TLogRow logRow = ParseLogRow(row2Str);
  399. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::WARN);
  400. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  401. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx1/ctx2} level2 - begin");
  402. }
  403. {
  404. TLogRow logRow = ParseLogRow(row3Str);
  405. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::ERROR);
  406. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  407. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx3} level3");
  408. }
  409. {
  410. TLogRow logRow = ParseLogRow(row4Str);
  411. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::WARN);
  412. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  413. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx1/ctx2} level2 - end");
  414. }
  415. {
  416. TLogRow logRow = ParseLogRow(row5Str);
  417. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  418. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  419. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "{ctx1} level1 - end");
  420. }
  421. }
  422. Y_UNIT_TEST(Profiling) {
  423. TStringStream out;
  424. YqlLoggerScope logger(&out);
  425. {
  426. YQL_PROFILE_SCOPE(INFO, "scope1");
  427. }
  428. YQL_PROFILE_BLOCK(WARN, "block1") {
  429. Sleep(TDuration::MilliSeconds(2));
  430. }
  431. YQL_PROFILE_BLOCK(ERROR, "block2") {
  432. Sleep(TDuration::MilliSeconds(1200));
  433. }
  434. bool isExecuted = false;
  435. YQL_PROFILE_BLOCK(TRACE, "block3") { // log will be filtered out
  436. isExecuted = true;
  437. }
  438. UNIT_ASSERT(isExecuted);
  439. TString row1Str, row2Str, row3Str, _;
  440. Split(out.Str(), '\n', row1Str, row2Str, row3Str, _);
  441. {
  442. TLogRow logRow = ParseLogRow(row1Str);
  443. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  444. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Perf);
  445. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Performance);
  446. std::regex re("Execution of \\[scope1\\] took [0-9\\.]+us");
  447. bool isMatch = std::regex_match(logRow.Message.c_str(), re);
  448. UNIT_ASSERT_C(isMatch, "Unexpected message: " << logRow.Message);
  449. }
  450. {
  451. TLogRow logRow = ParseLogRow(row2Str);
  452. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::WARN);
  453. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Perf);
  454. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Performance);
  455. std::regex re("Execution of \\[block1\\] took [0-9\\.]+ms");
  456. bool isMatch = std::regex_match(logRow.Message.c_str(), re);
  457. UNIT_ASSERT_C(isMatch, "Unexpected message: " << logRow.Message);
  458. }
  459. {
  460. TLogRow logRow = ParseLogRow(row3Str);
  461. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::ERROR);
  462. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Perf);
  463. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Performance);
  464. std::regex re("Execution of \\[block2\\] took [0-9\\.]+s");
  465. bool isMatch = std::regex_match(logRow.Message.c_str(), re);
  466. UNIT_ASSERT_C(isMatch, "Unexpected message: " << logRow.Message);
  467. }
  468. }
  469. int Func1(int a, char b) {
  470. YQL_PROFILE_FUNC(INFO);
  471. return a + b;
  472. }
  473. int Func2(int a, char b) {
  474. YQL_PROFILE_FUNCSIG(WARN);
  475. return a + b;
  476. }
  477. Y_UNIT_TEST(ProfilingFuncs) {
  478. TStringStream out;
  479. YqlLoggerScope logger(&out);
  480. Func1(1, 2);
  481. Func2(1, 2);
  482. TString row1Str, row2Str, _;
  483. Split(out.Str(), '\n', row1Str, row2Str, _);
  484. {
  485. TLogRow logRow = ParseLogRow(row1Str);
  486. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  487. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Perf);
  488. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Performance);
  489. std::regex re("Execution of \\[Func1\\] took [0-9\\.]+us");
  490. bool isMatch = std::regex_match(logRow.Message.c_str(), re);
  491. UNIT_ASSERT_C(isMatch, "Unexpected message: " << logRow.Message);
  492. }
  493. {
  494. TLogRow logRow = ParseLogRow(row2Str);
  495. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::WARN);
  496. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Perf);
  497. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Performance);
  498. #ifdef _win_
  499. std::regex re("Execution of \\[int __cdecl NTestSuiteTLogTest::Func2\\(int, char\\)\\] took [0-9\\.]+us");
  500. #else
  501. std::regex re("Execution of \\[int NTestSuiteTLogTest::Func2\\(int, char\\)\\] took [0-9\\.]+us");
  502. #endif
  503. bool isMatch = std::regex_match(logRow.Message.c_str(), re);
  504. UNIT_ASSERT_C(isMatch, "Unexpected message: " << logRow.Message);
  505. }
  506. }
  507. Y_UNIT_TEST(Limit1) {
  508. size_t limit = 0;
  509. {
  510. TStringStream out;
  511. YqlLoggerScope logger(&out);
  512. YqlLogger().UpdateProcInfo("proc");
  513. YQL_CLOG(INFO, Core) << "message1";
  514. limit = out.Str().length() * 2 - 7; // Not more than 2 log lines
  515. }
  516. TStringStream out;
  517. YqlLoggerScope logger(&out);
  518. YqlLogger().UpdateProcInfo("proc");
  519. YqlLogger().SetMaxLogLimit(limit);
  520. YQL_CLOG(INFO, Core) << "message1";
  521. YQL_CLOG(INFO, Core) << "message2";
  522. YQL_CLOG(INFO, Core) << "message3";
  523. TString row1Str, row2Str, row3Str, _;
  524. Split(out.Str(), '\n', row1Str, row2Str, row3Str, _);
  525. {
  526. TLogRow logRow = ParseLogRow(row1Str);
  527. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  528. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Core);
  529. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "message1");
  530. }
  531. {
  532. TLogRow logRow = ParseLogRow(row2Str);
  533. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  534. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Core);
  535. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "message2");
  536. }
  537. {
  538. TLogRow logRow = ParseLogRow(row3Str);
  539. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::FATAL);
  540. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  541. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "Log is truncated by limit");
  542. }
  543. }
  544. Y_UNIT_TEST(Limit2) {
  545. size_t limit = 0;
  546. {
  547. TStringStream out;
  548. YqlLoggerScope logger(&out);
  549. YqlLogger().UpdateProcInfo("proc");
  550. YQL_CLOG(INFO, Core) << "message1";
  551. limit = out.Str().length() * 2 - 7; // Not more than 2 log lines
  552. }
  553. TStringStream out;
  554. YqlLoggerScope logger(&out);
  555. YqlLogger().UpdateProcInfo("proc");
  556. YqlLogger().SetMaxLogLimit(limit);
  557. YQL_CLOG(INFO, Core) << "message1";
  558. YQL_CLOG(INFO, Core) << "message2";
  559. YQL_CLOG(WARN, Core) << "message3";
  560. TString row1Str, row2Str, row3Str, row4Str, _;
  561. Split(out.Str(), '\n', row1Str, row2Str, row3Str, row4Str, _);
  562. {
  563. TLogRow logRow = ParseLogRow(row1Str);
  564. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  565. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Core);
  566. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "message1");
  567. }
  568. {
  569. TLogRow logRow = ParseLogRow(row2Str);
  570. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::INFO);
  571. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Core);
  572. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "message2");
  573. }
  574. {
  575. TLogRow logRow = ParseLogRow(row3Str);
  576. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::FATAL);
  577. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Default);
  578. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "Log is truncated by limit");
  579. }
  580. {
  581. TLogRow logRow = ParseLogRow(row4Str);
  582. UNIT_ASSERT_EQUAL(logRow.Level, ELevel::WARN);
  583. UNIT_ASSERT_EQUAL(logRow.Component, EComponent::Core);
  584. UNIT_ASSERT_STRINGS_EQUAL(logRow.Message, "message3");
  585. }
  586. }
  587. }