4
4
#include < library/cpp/colorizer/colors.h>
5
5
#include < library/cpp/json/json_reader.h>
6
6
7
+ #include < ydb/core/blob_depot/mon_main.h>
8
+ #include < ydb/core/fq/libs/compute/common/utils.h>
9
+
7
10
#include < ydb/public/lib/json_value/ydb_json_value.h>
8
11
#include < ydb/public/lib/ydb_cli/common/format.h>
9
12
10
13
11
14
namespace NKqpRun {
12
15
16
+ namespace {
17
+
18
+ TString FormatNumber (i64 number) {
19
+ if (number < 0 ) {
20
+ return TStringBuilder () << " -" << FormatNumber (-number);
21
+ }
22
+
23
+ if (number < 1000 ) {
24
+ return ToString (number);
25
+ }
26
+
27
+ return TStringBuilder () << FormatNumber (number / 1000 ) << " '" << (number % 1000 ) / 100 << (number % 100 ) / 10 << number % 10 ;
28
+ }
29
+
30
+ void PrintStatistic (const TString& fullStatistic, const THashMap<TString, i64>& flatStatistic, const NFq::TPublicStat& publicStatistic, IOutputStream& output) {
31
+ output << " \n Flat statistic:" << Endl;
32
+ for (const auto & [propery, value] : flatStatistic) {
33
+ TString valueString = ToString (value);
34
+ if (propery.find (" Bytes" ) != TString::npos || propery.find (" Source" ) != TString::npos) {
35
+ valueString = NKikimr::NBlobDepot::FormatByteSize (value);
36
+ } else if (propery.find (" TimeUs" ) != TString::npos) {
37
+ valueString = NFq::FormatDurationUs (value);
38
+ } else if (propery.find (" TimeMs" ) != TString::npos) {
39
+ valueString = NFq::FormatDurationMs (value);
40
+ } else {
41
+ valueString = FormatNumber (value);
42
+ }
43
+ output << propery << " = " << valueString << Endl;
44
+ }
45
+
46
+ output << " \n Public statistic:" << Endl;
47
+ if (auto memoryUsageBytes = publicStatistic.MemoryUsageBytes ) {
48
+ output << " MemoryUsage = " << NKikimr::NBlobDepot::FormatByteSize (*memoryUsageBytes) << Endl;
49
+ }
50
+ if (auto cpuUsageUs = publicStatistic.CpuUsageUs ) {
51
+ output << " CpuUsage = " << NFq::FormatDurationUs (*cpuUsageUs) << Endl;
52
+ }
53
+ if (auto inputBytes = publicStatistic.InputBytes ) {
54
+ output << " InputSize = " << NKikimr::NBlobDepot::FormatByteSize (*inputBytes) << Endl;
55
+ }
56
+ if (auto outputBytes = publicStatistic.OutputBytes ) {
57
+ output << " OutputSize = " << NKikimr::NBlobDepot::FormatByteSize (*outputBytes) << Endl;
58
+ }
59
+ if (auto sourceInputRecords = publicStatistic.SourceInputRecords ) {
60
+ output << " SourceInputRecords = " << FormatNumber (*sourceInputRecords) << Endl;
61
+ }
62
+ if (auto sinkOutputRecords = publicStatistic.SinkOutputRecords ) {
63
+ output << " SinkOutputRecords = " << FormatNumber (*sinkOutputRecords) << Endl;
64
+ }
65
+ if (auto runningTasks = publicStatistic.RunningTasks ) {
66
+ output << " RunningTasks = " << FormatNumber (*runningTasks) << Endl;
67
+ }
68
+
69
+ output << " \n Full statistic:" << Endl;
70
+ NJson::TJsonValue statsJson;
71
+ NJson::ReadJsonTree (fullStatistic, &statsJson);
72
+ NJson::WriteJson (&output, &statsJson, true , true , true );
73
+ output << Endl;
74
+ }
75
+
76
+ } // anonymous namespace
77
+
78
+
13
79
// // TKqpRunner::TImpl
14
80
15
81
class TKqpRunner ::TImpl {
@@ -22,6 +88,7 @@ class TKqpRunner::TImpl {
22
88
explicit TImpl (const TRunnerOptions& options)
23
89
: Options_(options)
24
90
, YdbSetup_(options.YdbSettings)
91
+ , StatProcessor_(NFq::CreateStatProcessor(" stat_full" ))
25
92
, CerrColors_(NColorizer::AutoColors(Cerr))
26
93
, CoutColors_(NColorizer::AutoColors(Cout))
27
94
{}
@@ -63,7 +130,7 @@ class TKqpRunner::TImpl {
63
130
TRequestResult status;
64
131
switch (queryType) {
65
132
case EQueryType::ScriptQuery:
66
- status = YdbSetup_.QueryRequest (query, action, traceId, meta, ResultSets_);
133
+ status = YdbSetup_.QueryRequest (query, action, traceId, meta, ResultSets_, GetProgressCallback () );
67
134
break ;
68
135
69
136
case EQueryType::YqlScriptQuery:
@@ -132,9 +199,16 @@ class TKqpRunner::TImpl {
132
199
private:
133
200
bool WaitScriptExecutionOperation () {
134
201
ExecutionMeta_ = TExecutionMeta ();
202
+
203
+ TDuration getOperationPeriod = TDuration::Seconds (1 );
204
+ if (auto progressStatsPeriodMs = Options_.YdbSettings .AppConfig .GetQueryServiceConfig ().GetProgressStatsPeriodMs ()) {
205
+ getOperationPeriod = TDuration::MilliSeconds (progressStatsPeriodMs);
206
+ }
207
+
135
208
TRequestResult status;
136
209
while (true ) {
137
210
status = YdbSetup_.GetScriptExecutionOperationRequest (ExecutionOperation_, ExecutionMeta_);
211
+ PrintScriptProgress (ExecutionMeta_.Plan );
138
212
139
213
if (ExecutionMeta_.Ready ) {
140
214
break ;
@@ -145,7 +219,7 @@ class TKqpRunner::TImpl {
145
219
return false ;
146
220
}
147
221
148
- Sleep (TDuration::Seconds ( 1 ) );
222
+ Sleep (getOperationPeriod );
149
223
}
150
224
151
225
PrintScriptAst (ExecutionMeta_.Ast );
@@ -190,8 +264,8 @@ class TKqpRunner::TImpl {
190
264
}
191
265
}
192
266
193
- void PrintScriptPlan (const TString& plan) const {
194
- if (!Options_. ScriptQueryPlanOutput || ! plan) {
267
+ void PrintPlan (const TString& plan, IOutputStream* output ) const {
268
+ if (!plan) {
195
269
return ;
196
270
}
197
271
@@ -201,12 +275,57 @@ class TKqpRunner::TImpl {
201
275
return ;
202
276
}
203
277
204
- Cout << CoutColors_.Cyan () << " Writing script query plan" << CoutColors_.Default () << Endl;
205
-
206
- NYdb::NConsoleClient::TQueryPlanPrinter printer (Options_.PlanOutputFormat , true , *Options_.ScriptQueryPlanOutput );
278
+ NYdb::NConsoleClient::TQueryPlanPrinter printer (Options_.PlanOutputFormat , true , *output);
207
279
printer.Print (plan);
208
280
}
209
281
282
+ void PrintScriptPlan (const TString& plan) const {
283
+ if (Options_.ScriptQueryPlanOutput ) {
284
+ Cout << CoutColors_.Cyan () << " Writing script query plan" << CoutColors_.Default () << Endl;
285
+ PrintPlan (plan, Options_.ScriptQueryPlanOutput );
286
+ }
287
+ }
288
+
289
+ void PrintScriptProgress (const TString& plan) const {
290
+ if (Options_.InProgressStatisticOutputFile ) {
291
+ TFileOutput outputStream (*Options_.InProgressStatisticOutputFile );
292
+ outputStream << TInstant::Now ().ToIsoStringLocal () << " Script in progress statistic" << Endl;
293
+
294
+ auto convertedPlan = plan;
295
+ try {
296
+ convertedPlan = StatProcessor_->ConvertPlan (plan);
297
+ } catch (const NJson::TJsonException& ex) {
298
+ outputStream << " Error plan conversion: " << ex.what () << Endl;
299
+ }
300
+
301
+ try {
302
+ double cpuUsage = 0.0 ;
303
+ auto stat = StatProcessor_->GetQueryStat (convertedPlan, cpuUsage);
304
+ outputStream << " \n CPU usage: " << cpuUsage << Endl;
305
+
306
+ auto flatStat = StatProcessor_->GetFlatStat (convertedPlan);
307
+ auto publicStat = StatProcessor_->GetPublicStat (stat);
308
+
309
+ PrintStatistic (stat, flatStat, publicStat, outputStream);
310
+ } catch (const NJson::TJsonException& ex) {
311
+ outputStream << " Error stat conversion: " << ex.what () << Endl;
312
+ }
313
+
314
+ outputStream << " \n Plan visualization:" << Endl;
315
+ PrintPlan (convertedPlan, &outputStream);
316
+
317
+ outputStream.Finish ();
318
+ }
319
+ }
320
+
321
+ TProgressCallback GetProgressCallback () {
322
+ return [this ](const NKikimrKqp::TEvExecuterProgress& executerProgress) mutable {
323
+ const TString& plan = executerProgress.GetQueryPlan ();
324
+ ExecutionMeta_.Plan = plan;
325
+ PrintScriptProgress (plan);
326
+ };
327
+ }
328
+
210
329
void PrintScriptResult (const Ydb::ResultSet& resultSet) const {
211
330
switch (Options_.ResultOutputFormat ) {
212
331
case TRunnerOptions::EResultOutputFormat::RowsJson: {
@@ -241,6 +360,7 @@ class TKqpRunner::TImpl {
241
360
TRunnerOptions Options_;
242
361
243
362
TYdbSetup YdbSetup_;
363
+ std::unique_ptr<NFq::IPlanStatProcessor> StatProcessor_;
244
364
NColorizer::TColors CerrColors_;
245
365
NColorizer::TColors CoutColors_;
246
366
0 commit comments