aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoromgronny <omgronny@yandex-team.com>2024-10-11 21:16:54 +0300
committeromgronny <omgronny@yandex-team.com>2024-10-11 21:28:33 +0300
commitc7307fc40d61e2a996fd7c22ee9ef52663897b3b (patch)
treecf38637a1ef654e984c4847260253dd8195bff66
parent1df197e6035ea9826bfedee7d48812e318ba9c7a (diff)
downloadydb-c7307fc40d61e2a996fd7c22ee9ef52663897b3b.tar.gz
YT-21938: Introduce get_job_trace
* Changelog entry\ Type: feature\ Component: proxy Add the handler that gets the job’s trace events. commit_hash:c9d1a6d57e886a266967d57065bd3948882808c7
-rw-r--r--yt/cpp/mapreduce/client/client.cpp8
-rw-r--r--yt/cpp/mapreduce/client/client.h4
-rw-r--r--yt/cpp/mapreduce/interface/client.h12
-rw-r--r--yt/cpp/mapreduce/interface/fwd.h3
-rw-r--r--yt/cpp/mapreduce/interface/operation.h64
-rw-r--r--yt/cpp/mapreduce/raw_client/raw_requests.cpp49
-rw-r--r--yt/cpp/mapreduce/raw_client/raw_requests.h6
-rw-r--r--yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.cpp9
-rw-r--r--yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.h4
-rw-r--r--yt/yt/client/api/delegating_client.h5
-rw-r--r--yt/yt/client/api/operation_client.cpp13
-rw-r--r--yt/yt/client/api/operation_client.h28
-rw-r--r--yt/yt/client/api/rpc_proxy/api_service_proxy.h1
-rw-r--r--yt/yt/client/api/rpc_proxy/client_impl.cpp35
-rw-r--r--yt/yt/client/api/rpc_proxy/client_impl.h4
-rw-r--r--yt/yt/client/api/rpc_proxy/helpers.cpp24
-rw-r--r--yt/yt/client/api/rpc_proxy/helpers.h8
-rw-r--r--yt/yt/client/driver/driver.cpp1
-rw-r--r--yt/yt/client/driver/scheduler_commands.cpp46
-rw-r--r--yt/yt/client/driver/scheduler_commands.h14
-rw-r--r--yt/yt/client/federated/client.cpp1
-rw-r--r--yt/yt/client/hedging/hedging.cpp1
-rw-r--r--yt/yt/client/scheduler/public.h6
-rw-r--r--yt/yt/client/unittests/mock/client.h5
-rw-r--r--yt/yt/core/ytree/tree_builder.h1
-rw-r--r--yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto31
26 files changed, 382 insertions, 1 deletions
diff --git a/yt/cpp/mapreduce/client/client.cpp b/yt/cpp/mapreduce/client/client.cpp
index 9e2885bbe0..9dab176bde 100644
--- a/yt/cpp/mapreduce/client/client.cpp
+++ b/yt/cpp/mapreduce/client/client.cpp
@@ -1243,6 +1243,14 @@ IFileReaderPtr TClient::GetJobStderr(
return NRawClient::GetJobStderr(Context_, operationId, jobId, options);
}
+std::vector<TJobTraceEvent> TClient::GetJobTrace(
+ const TOperationId& operationId,
+ const TGetJobTraceOptions& options)
+{
+ CheckShutdown();
+ return NRawClient::GetJobTrace(ClientRetryPolicy_->CreatePolicyForGenericRequest(), Context_, operationId, options);
+}
+
TNode::TListType TClient::SkyShareTable(
const std::vector<TYPath>& tablePaths,
const TSkyShareTableOptions& options)
diff --git a/yt/cpp/mapreduce/client/client.h b/yt/cpp/mapreduce/client/client.h
index 5de00285ef..32c458316d 100644
--- a/yt/cpp/mapreduce/client/client.h
+++ b/yt/cpp/mapreduce/client/client.h
@@ -449,6 +449,10 @@ public:
const TJobId& jobId,
const TGetJobStderrOptions& options = TGetJobStderrOptions()) override;
+ std::vector<TJobTraceEvent> GetJobTrace(
+ const TOperationId& operationId,
+ const TGetJobTraceOptions& options = TGetJobTraceOptions()) override;
+
TNode::TListType SkyShareTable(
const std::vector<TYPath>& tablePaths,
const TSkyShareTableOptions& options = TSkyShareTableOptions()) override;
diff --git a/yt/cpp/mapreduce/interface/client.h b/yt/cpp/mapreduce/interface/client.h
index 56efa3c23c..3032025140 100644
--- a/yt/cpp/mapreduce/interface/client.h
+++ b/yt/cpp/mapreduce/interface/client.h
@@ -493,6 +493,18 @@ public:
const TGetJobStderrOptions& options = TGetJobStderrOptions()) = 0;
///
+ /// @brief Get trace of a job.
+ ///
+ /// @ref NYT::TErrorResponse exception is thrown if it is missing.
+ ///
+ /// @note YT doesn't store all job traces.
+ ///
+ /// @see [YT doc](https://ytsaurus.tech/docs/en/api/commands.html#get_job_trace)
+ virtual std::vector<TJobTraceEvent> GetJobTrace(
+ const TOperationId& operationId,
+ const TGetJobTraceOptions& options = TGetJobTraceOptions()) = 0;
+
+ ///
/// @brief Create one or several rbtorrents for files in a blob table.
///
/// If specified, one torrent is created for each value of `KeyColumns` option.
diff --git a/yt/cpp/mapreduce/interface/fwd.h b/yt/cpp/mapreduce/interface/fwd.h
index 0434c03d8b..485b45129a 100644
--- a/yt/cpp/mapreduce/interface/fwd.h
+++ b/yt/cpp/mapreduce/interface/fwd.h
@@ -157,6 +157,7 @@ namespace NYT {
using TTabletCellId = TGUID;
using TReplicaId = TGUID;
using TJobId = TGUID;
+ using TJobTraceId = TGUID;
using TYPath = TString;
using TLocalFilePath = TString;
@@ -370,6 +371,8 @@ namespace NYT {
struct TListJobsOptions;
+ struct TGetJobTraceOptions;
+
struct IOperationClient;
enum class EFinishedJobState : int;
diff --git a/yt/cpp/mapreduce/interface/operation.h b/yt/cpp/mapreduce/interface/operation.h
index 9a85049886..f2de3ea3bd 100644
--- a/yt/cpp/mapreduce/interface/operation.h
+++ b/yt/cpp/mapreduce/interface/operation.h
@@ -3048,6 +3048,70 @@ struct TGetFailedJobInfoOptions
////////////////////////////////////////////////////////////////////////////////
///
+/// @brief Options for @ref NYT::IClient::GetJobTrace.
+struct TGetJobTraceOptions
+{
+ /// @cond Doxygen_Suppress
+ using TSelf = TGetJobTraceOptions;
+ /// @endcond
+
+ ///
+ /// @brief Id of the job.
+ FLUENT_FIELD_OPTION(TJobId, JobId);
+
+ ///
+ /// @brief Id of the trace.
+ FLUENT_FIELD_OPTION(TJobTraceId, TraceId);
+
+ ///
+ /// @brief Search for traces with time >= `FromTime`.
+ FLUENT_FIELD_OPTION(i64, FromTime);
+
+ ///
+ /// @brief Search for traces with time <= `ToTime`.
+ FLUENT_FIELD_OPTION(i64, ToTime);
+
+ ///
+ /// @brief Search for traces with event index >= `FromEventIndex`.
+ FLUENT_FIELD_OPTION(i64, FromEventIndex);
+
+ ///
+ /// @brief Search for traces with event index >= `ToEventIndex`.
+ FLUENT_FIELD_OPTION(i64, ToEventIndex);
+};
+
+///
+/// @brief Response for @ref NYT::IOperation::GetJobTrace.
+struct TJobTraceEvent
+{
+ ///
+ /// @brief Id of the operation.
+ TOperationId OperationId;
+
+ ///
+ /// @brief Id of the job.
+ TJobId JobId;
+
+ ///
+ /// @brief Id of the trace.
+ TJobTraceId TraceId;
+
+ ///
+ /// @brief Index of the trace event.
+ i64 EventIndex;
+
+ ///
+ /// @brief Raw evenr in json format.
+ TString Event;
+
+ ///
+ /// @brief Time of the event.
+ TInstant EventTime;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+///
/// @brief Interface representing an operation.
struct IOperation
: public TThrRefBase
diff --git a/yt/cpp/mapreduce/raw_client/raw_requests.cpp b/yt/cpp/mapreduce/raw_client/raw_requests.cpp
index 2f9610a1ca..59868c599e 100644
--- a/yt/cpp/mapreduce/raw_client/raw_requests.cpp
+++ b/yt/cpp/mapreduce/raw_client/raw_requests.cpp
@@ -783,6 +783,55 @@ IFileReaderPtr GetJobStderr(
return new TResponseReader(context, std::move(header));
}
+TJobTraceEvent ParseJobTraceEvent(const TNode& node)
+{
+ const auto& mapNode = node.AsMap();
+ TJobTraceEvent result;
+
+ if (auto idNode = mapNode.FindPtr("operation_id")) {
+ result.OperationId = GetGuid(idNode->AsString());
+ }
+ if (auto idNode = mapNode.FindPtr("job_id")) {
+ result.JobId = GetGuid(idNode->AsString());
+ }
+ if (auto idNode = mapNode.FindPtr("trace_id")) {
+ result.TraceId = GetGuid(idNode->AsString());
+ }
+ if (auto eventIndexNode = mapNode.FindPtr("event_index")) {
+ result.EventIndex = eventIndexNode->AsInt64();
+ }
+ if (auto eventNode = mapNode.FindPtr("event")) {
+ result.Event = eventNode->AsString();
+ }
+ if (auto eventTimeNode = mapNode.FindPtr("event_time")) {
+ result.EventTime = TInstant::ParseIso8601(eventTimeNode->AsString());;
+ }
+
+ return result;
+}
+
+std::vector<TJobTraceEvent> GetJobTrace(
+ const IRequestRetryPolicyPtr& retryPolicy,
+ const TClientContext& context,
+ const TOperationId& operationId,
+ const TGetJobTraceOptions& options)
+{
+ THttpHeader header("GET", "get_job_trace");
+ header.MergeParameters(SerializeParamsForGetJobTrace(operationId, options));
+ auto responseInfo = RetryRequestWithPolicy(retryPolicy, context, header);
+ auto resultNode = NodeFromYsonString(responseInfo.Response);
+
+ std::vector<TJobTraceEvent> result;
+
+ const auto& traceEventNodesList = resultNode.AsList();
+ result.reserve(traceEventNodesList.size());
+ for (const auto& traceEventNode : traceEventNodesList) {
+ result.push_back(ParseJobTraceEvent(traceEventNode));
+ }
+
+ return result;
+}
+
TMaybe<TYPath> GetFileFromCache(
const IRequestRetryPolicyPtr& retryPolicy,
const TClientContext& context,
diff --git a/yt/cpp/mapreduce/raw_client/raw_requests.h b/yt/cpp/mapreduce/raw_client/raw_requests.h
index c2d1a53b51..0a183d617c 100644
--- a/yt/cpp/mapreduce/raw_client/raw_requests.h
+++ b/yt/cpp/mapreduce/raw_client/raw_requests.h
@@ -257,6 +257,12 @@ TString GetJobStderrWithRetries(
const TJobId& jobId,
const TGetJobStderrOptions& options = TGetJobStderrOptions());
+std::vector<TJobTraceEvent> GetJobTrace(
+ const IRequestRetryPolicyPtr& retryPolicy,
+ const TClientContext& context,
+ const TOperationId& operationId,
+ const TGetJobTraceOptions& options = TGetJobTraceOptions());
+
//
// File cache
//
diff --git a/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.cpp b/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.cpp
index a638ac581d..bebc59ec91 100644
--- a/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.cpp
+++ b/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.cpp
@@ -525,6 +525,15 @@ TNode SerializeParamsForGetJob(
return result;
}
+TNode SerializeParamsForGetJobTrace(
+ const TOperationId& operationId,
+ const TGetJobTraceOptions& /* options */)
+{
+ TNode result;
+ SetOperationIdParam(&result, operationId);
+ return result;
+}
+
TNode SerializeParamsForListJobs(
const TOperationId& operationId,
const TListJobsOptions& options)
diff --git a/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.h b/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.h
index a7ab35d91d..69a4888267 100644
--- a/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.h
+++ b/yt/cpp/mapreduce/raw_client/rpc_parameters_serialization.h
@@ -126,6 +126,10 @@ TNode SerializeParamsForListJobs(
const TOperationId& operationId,
const TListJobsOptions& options);
+TNode SerializeParamsForGetJobTrace(
+ const TOperationId& operationId,
+ const TGetJobTraceOptions& options);
+
TNode SerializeParametersForInsertRows(
const TString& pathPrefix,
const TYPath& path,
diff --git a/yt/yt/client/api/delegating_client.h b/yt/yt/client/api/delegating_client.h
index c14f2d49d6..5b5e9accf3 100644
--- a/yt/yt/client/api/delegating_client.h
+++ b/yt/yt/client/api/delegating_client.h
@@ -516,6 +516,11 @@ public:
const TGetJobStderrOptions& options),
(operationIdOrAlias, jobId, options))
+ DELEGATE_METHOD(TFuture<std::vector<TJobTraceEvent>>, GetJobTrace, (
+ const NScheduler::TOperationIdOrAlias& operationIdOrAlias,
+ const TGetJobTraceOptions& options),
+ (operationIdOrAlias, options))
+
DELEGATE_METHOD(TFuture<TSharedRef>, GetJobFailContext, (
const NScheduler::TOperationIdOrAlias& operationIdOrAlias,
NJobTrackerClient::TJobId jobId,
diff --git a/yt/yt/client/api/operation_client.cpp b/yt/yt/client/api/operation_client.cpp
index 4e1816a6e7..8f8dbb355b 100644
--- a/yt/yt/client/api/operation_client.cpp
+++ b/yt/yt/client/api/operation_client.cpp
@@ -217,6 +217,19 @@ void Serialize(const TJob& job, NYson::IYsonConsumer* consumer, TStringBuf idKey
.EndMap();
}
+void Serialize(const TJobTraceEvent& traceEvent, NYson::IYsonConsumer* consumer)
+{
+ NYTree::BuildYsonFluently(consumer)
+ .BeginMap()
+ .Item("operation_id").Value(traceEvent.OperationId)
+ .Item("job_id").Value(traceEvent.JobId)
+ .Item("trace_id").Value(traceEvent.TraceId)
+ .Item("event_index").Value(traceEvent.EventIndex)
+ .Item("event").Value(traceEvent.Event)
+ .Item("event_time").Value(traceEvent.EventTime.MicroSeconds())
+ .EndMap();
+}
+
////////////////////////////////////////////////////////////////////////////////
void TListOperationsAccessFilter::Register(TRegistrar registrar)
diff --git a/yt/yt/client/api/operation_client.h b/yt/yt/client/api/operation_client.h
index 48687497da..d5072db1fc 100644
--- a/yt/yt/client/api/operation_client.h
+++ b/yt/yt/client/api/operation_client.h
@@ -89,6 +89,18 @@ struct TGetJobStderrOptions
std::optional<i64> Offset;
};
+struct TGetJobTraceOptions
+ : public TTimeoutOptions
+ , public TMasterReadOptions
+{
+ std::optional<NJobTrackerClient::TJobId> JobId;
+ std::optional<NScheduler::TJobTraceId> TraceId;
+ std::optional<i64> FromTime;
+ std::optional<i64> ToTime;
+ std::optional<i64> FromEventIndex;
+ std::optional<i64> ToEventIndex;
+};
+
struct TGetJobFailContextOptions
: public TTimeoutOptions
, public TMasterReadOptions
@@ -346,6 +358,18 @@ struct TJob
void Serialize(const TJob& job, NYson::IYsonConsumer* consumer, TStringBuf idKey);
+struct TJobTraceEvent
+{
+ NJobTrackerClient::TOperationId OperationId;
+ NJobTrackerClient::TJobId JobId;
+ NScheduler::TJobTraceId TraceId;
+ i64 EventIndex;
+ TString Event;
+ TInstant EventTime;
+};
+
+void Serialize(const TJobTraceEvent& traceEvent, NYson::IYsonConsumer* consumer);
+
struct TListJobsStatistics
{
TEnumIndexedArray<NJobTrackerClient::EJobState, i64> StateCounts;
@@ -443,6 +467,10 @@ struct IOperationClient
NJobTrackerClient::TJobId jobId,
const TGetJobStderrOptions& options = {}) = 0;
+ virtual TFuture<std::vector<TJobTraceEvent>> GetJobTrace(
+ const NScheduler::TOperationIdOrAlias& operationIdOrAlias,
+ const TGetJobTraceOptions& options = {}) = 0;
+
virtual TFuture<TSharedRef> GetJobFailContext(
const NScheduler::TOperationIdOrAlias& operationIdOrAlias,
NJobTrackerClient::TJobId jobId,
diff --git a/yt/yt/client/api/rpc_proxy/api_service_proxy.h b/yt/yt/client/api/rpc_proxy/api_service_proxy.h
index 6b00c7470a..4dcb04c33f 100644
--- a/yt/yt/client/api/rpc_proxy/api_service_proxy.h
+++ b/yt/yt/client/api/rpc_proxy/api_service_proxy.h
@@ -121,6 +121,7 @@ public:
DEFINE_RPC_PROXY_METHOD(NRpcProxy::NProto, GetJobInputPaths);
DEFINE_RPC_PROXY_METHOD(NRpcProxy::NProto, GetJobSpec);
DEFINE_RPC_PROXY_METHOD(NRpcProxy::NProto, GetJobStderr);
+ DEFINE_RPC_PROXY_METHOD(NRpcProxy::NProto, GetJobTrace);
DEFINE_RPC_PROXY_METHOD(NRpcProxy::NProto, GetJobFailContext);
DEFINE_RPC_PROXY_METHOD(NRpcProxy::NProto, AbandonJob);
DEFINE_RPC_PROXY_METHOD(NRpcProxy::NProto, PollJobShell);
diff --git a/yt/yt/client/api/rpc_proxy/client_impl.cpp b/yt/yt/client/api/rpc_proxy/client_impl.cpp
index b9e4944381..50bf51f247 100644
--- a/yt/yt/client/api/rpc_proxy/client_impl.cpp
+++ b/yt/yt/client/api/rpc_proxy/client_impl.cpp
@@ -1328,6 +1328,41 @@ TFuture<TGetJobStderrResponse> TClient::GetJobStderr(
}));
}
+TFuture<std::vector<TJobTraceEvent>> TClient::GetJobTrace(
+ const TOperationIdOrAlias& operationIdOrAlias,
+ const TGetJobTraceOptions& options)
+{
+ auto proxy = CreateApiServiceProxy();
+
+ auto req = proxy.GetJobTrace();
+ SetTimeoutOptions(*req, options);
+
+ NScheduler::ToProto(req, operationIdOrAlias);
+ if (options.JobId) {
+ ToProto(req->mutable_job_id(), *options.JobId);
+ }
+ if (options.TraceId) {
+ ToProto(req->mutable_trace_id(), *options.TraceId);
+ }
+ if (options.FromTime) {
+ req->set_from_time(*options.FromTime);
+ }
+ if (options.ToTime) {
+ req->set_to_time(*options.ToTime);
+ }
+ if (options.FromEventIndex) {
+ req->set_from_event_index(*options.FromEventIndex);
+ }
+ if (options.ToEventIndex) {
+ req->set_to_event_index(*options.ToEventIndex);
+ }
+
+ return req->Invoke().Apply(BIND([] (const TApiServiceProxy::TRspGetJobTracePtr& rsp) {
+ return FromProto<std::vector<TJobTraceEvent>>(rsp->events());
+ }));
+}
+
+
TFuture<TSharedRef> TClient::GetJobFailContext(
const TOperationIdOrAlias& operationIdOrAlias,
NJobTrackerClient::TJobId jobId,
diff --git a/yt/yt/client/api/rpc_proxy/client_impl.h b/yt/yt/client/api/rpc_proxy/client_impl.h
index d3905300e3..9f8ee540a2 100644
--- a/yt/yt/client/api/rpc_proxy/client_impl.h
+++ b/yt/yt/client/api/rpc_proxy/client_impl.h
@@ -278,6 +278,10 @@ public:
NJobTrackerClient::TJobId jobId,
const NApi::TGetJobStderrOptions& options) override;
+ TFuture<std::vector<TJobTraceEvent>> GetJobTrace(
+ const NScheduler::TOperationIdOrAlias& operationIdOrAlias,
+ const NApi::TGetJobTraceOptions& options) override;
+
TFuture<TSharedRef> GetJobFailContext(
const NScheduler::TOperationIdOrAlias& operationIdOrAlias,
NJobTrackerClient::TJobId jobId,
diff --git a/yt/yt/client/api/rpc_proxy/helpers.cpp b/yt/yt/client/api/rpc_proxy/helpers.cpp
index a89368573c..af3b4b7eb6 100644
--- a/yt/yt/client/api/rpc_proxy/helpers.cpp
+++ b/yt/yt/client/api/rpc_proxy/helpers.cpp
@@ -426,6 +426,30 @@ void FromProto(
FromProto(&result->Errors, proto.errors());
}
+void ToProto(
+ NProto::TJobTraceEvent* proto,
+ const NApi::TJobTraceEvent& result)
+{
+ ToProto(proto->mutable_operation_id(), result.OperationId);
+ ToProto(proto->mutable_job_id(), result.JobId);
+ ToProto(proto->mutable_trace_id(), result.TraceId);
+ proto->set_event_index(result.EventIndex);
+ proto->set_event(result.Event);
+ proto->set_event_time(ToProto<i64>(result.EventTime));
+}
+
+void FromProto(
+ NApi::TJobTraceEvent* result,
+ const NProto::TJobTraceEvent& proto)
+{
+ FromProto(&result->OperationId, proto.operation_id());
+ FromProto(&result->JobId, proto.job_id());
+ FromProto(&result->TraceId, proto.trace_id());
+ result->EventIndex = proto.event_index();
+ result->Event = proto.event();
+ result->EventTime = TInstant::FromValue(proto.event_time());
+}
+
////////////////////////////////////////////////////////////////////////////////
// MISC
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/client/api/rpc_proxy/helpers.h b/yt/yt/client/api/rpc_proxy/helpers.h
index 9027337359..ca99986c72 100644
--- a/yt/yt/client/api/rpc_proxy/helpers.h
+++ b/yt/yt/client/api/rpc_proxy/helpers.h
@@ -106,6 +106,14 @@ void FromProto(
NApi::TListJobsResult* result,
const NProto::TListJobsResult& proto);
+void ToProto(
+ NProto::TJobTraceEvent* proto,
+ const NApi::TJobTraceEvent& result);
+
+void FromProto(
+ NApi::TJobTraceEvent* result,
+ const NProto::TJobTraceEvent& proto);
+
void ToProto(NProto::TColumnSchema* protoSchema, const NTableClient::TColumnSchema& schema);
void FromProto(NTableClient::TColumnSchema* schema, const NProto::TColumnSchema& protoSchema);
diff --git a/yt/yt/client/driver/driver.cpp b/yt/yt/client/driver/driver.cpp
index 19a0f3bdc5..4fb7783697 100644
--- a/yt/yt/client/driver/driver.cpp
+++ b/yt/yt/client/driver/driver.cpp
@@ -292,6 +292,7 @@ public:
REGISTER_ALL(TGetJobInputCommand, "get_job_input", Null, Binary, false, true );
REGISTER_ALL(TGetJobInputPathsCommand, "get_job_input_paths", Null, Structured, false, true );
REGISTER_ALL(TGetJobStderrCommand, "get_job_stderr", Null, Binary, false, true );
+ REGISTER_ALL(TGetJobTraceCommand, "get_job_trace", Null, Structured, false, true );
REGISTER_ALL(TGetJobFailContextCommand, "get_job_fail_context", Null, Binary, false, true );
REGISTER_ALL(TGetJobSpecCommand, "get_job_spec", Null, Structured, false, true );
REGISTER_ALL(TListOperationsCommand, "list_operations", Null, Structured, false, false);
diff --git a/yt/yt/client/driver/scheduler_commands.cpp b/yt/yt/client/driver/scheduler_commands.cpp
index 9cb7396725..53f82c7bf2 100644
--- a/yt/yt/client/driver/scheduler_commands.cpp
+++ b/yt/yt/client/driver/scheduler_commands.cpp
@@ -174,6 +174,52 @@ void TGetJobStderrCommand::DoExecute(ICommandContextPtr context)
////////////////////////////////////////////////////////////////////////////////
+void TGetJobTraceCommand::Register(TRegistrar registrar)
+{
+ registrar.ParameterWithUniversalAccessor<std::optional<TJobId>>(
+ "job_id",
+ [] (TThis* command) -> auto& {return command->Options.JobId; })
+ .Optional(/*init*/ false);
+
+ registrar.ParameterWithUniversalAccessor<std::optional<TJobTraceId>>(
+ "trace_id",
+ [] (TThis* command) -> auto& {return command->Options.TraceId; })
+ .Optional(/*init*/ false);
+
+ registrar.ParameterWithUniversalAccessor<std::optional<i64>>(
+ "from_event_index",
+ [] (TThis* command) -> auto& {return command->Options.FromEventIndex; })
+ .Optional(/*init*/ false);
+
+ registrar.ParameterWithUniversalAccessor<std::optional<i64>>(
+ "to_event_index",
+ [] (TThis* command) -> auto& {return command->Options.ToEventIndex; })
+ .Optional(/*init*/ false);
+
+ registrar.ParameterWithUniversalAccessor<std::optional<i64>>(
+ "from_time",
+ [] (TThis* command) -> auto& {return command->Options.FromTime; })
+ .Optional(/*init*/ false);
+
+ registrar.ParameterWithUniversalAccessor<std::optional<i64>>(
+ "to_time",
+ [] (TThis* command) -> auto& {return command->Options.ToTime; })
+ .Optional(/*init*/ false);
+}
+
+void TGetJobTraceCommand::DoExecute(ICommandContextPtr context)
+{
+ auto result = WaitFor(context->GetClient()->GetJobTrace(OperationIdOrAlias, Options))
+ .ValueOrThrow();
+
+ context->ProduceOutputValue(BuildYsonStringFluently()
+ .DoListFor(result, [&] (TFluentList fluent, const TJobTraceEvent& traceEvent) {
+ Serialize(traceEvent, fluent.GetConsumer());
+ }));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
void TGetJobFailContextCommand::Register(TRegistrar registrar)
{
registrar.Parameter("job_id", &TThis::JobId);
diff --git a/yt/yt/client/driver/scheduler_commands.h b/yt/yt/client/driver/scheduler_commands.h
index 280d55e331..59d1e9d21e 100644
--- a/yt/yt/client/driver/scheduler_commands.h
+++ b/yt/yt/client/driver/scheduler_commands.h
@@ -137,6 +137,20 @@ private:
////////////////////////////////////////////////////////////////////////////////
+class TGetJobTraceCommand
+ : public TSimpleOperationCommandBase<NApi::TGetJobTraceOptions>
+{
+public:
+ REGISTER_YSON_STRUCT_LITE(TGetJobTraceCommand);
+
+ static void Register(TRegistrar registrar);
+
+private:
+ void DoExecute(ICommandContextPtr context) override;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
class TGetJobFailContextCommand
: public TSimpleOperationCommandBase<NApi::TGetJobFailContextOptions>
{
diff --git a/yt/yt/client/federated/client.cpp b/yt/yt/client/federated/client.cpp
index a3410ff50a..ff1b7505d6 100644
--- a/yt/yt/client/federated/client.cpp
+++ b/yt/yt/client/federated/client.cpp
@@ -407,6 +407,7 @@ public:
UNIMPLEMENTED_METHOD(TFuture<NYson::TYsonString>, GetJobInputPaths, (NJobTrackerClient::TJobId, const TGetJobInputPathsOptions&));
UNIMPLEMENTED_METHOD(TFuture<NYson::TYsonString>, GetJobSpec, (NJobTrackerClient::TJobId, const TGetJobSpecOptions&));
UNIMPLEMENTED_METHOD(TFuture<TGetJobStderrResponse>, GetJobStderr, (const NScheduler::TOperationIdOrAlias&, NJobTrackerClient::TJobId, const TGetJobStderrOptions&));
+ UNIMPLEMENTED_METHOD(TFuture<std::vector<TJobTraceEvent>>, GetJobTrace, (const NScheduler::TOperationIdOrAlias&, const TGetJobTraceOptions&));
UNIMPLEMENTED_METHOD(TFuture<TSharedRef>, GetJobFailContext, (const NScheduler::TOperationIdOrAlias&, NJobTrackerClient::TJobId, const TGetJobFailContextOptions&));
UNIMPLEMENTED_METHOD(TFuture<TListOperationsResult>, ListOperations, (const TListOperationsOptions&));
UNIMPLEMENTED_METHOD(TFuture<TListJobsResult>, ListJobs, (const NScheduler::TOperationIdOrAlias&, const TListJobsOptions&));
diff --git a/yt/yt/client/hedging/hedging.cpp b/yt/yt/client/hedging/hedging.cpp
index ae0376bcda..707a6759b8 100644
--- a/yt/yt/client/hedging/hedging.cpp
+++ b/yt/yt/client/hedging/hedging.cpp
@@ -164,6 +164,7 @@ public:
UNSUPPORTED_METHOD(TFuture<NYson::TYsonString>, GetJobInputPaths, (NJobTrackerClient::TJobId, const TGetJobInputPathsOptions&));
UNSUPPORTED_METHOD(TFuture<NYson::TYsonString>, GetJobSpec, (NJobTrackerClient::TJobId, const TGetJobSpecOptions&));
UNSUPPORTED_METHOD(TFuture<TGetJobStderrResponse>, GetJobStderr, (const NScheduler::TOperationIdOrAlias&, NJobTrackerClient::TJobId, const TGetJobStderrOptions&));
+ UNSUPPORTED_METHOD(TFuture<std::vector<TJobTraceEvent>>, GetJobTrace, (const NScheduler::TOperationIdOrAlias&, const TGetJobTraceOptions&));
UNSUPPORTED_METHOD(TFuture<TSharedRef>, GetJobFailContext, (const NScheduler::TOperationIdOrAlias&, NJobTrackerClient::TJobId, const TGetJobFailContextOptions&));
UNSUPPORTED_METHOD(TFuture<TListOperationsResult>, ListOperations, (const TListOperationsOptions&));
UNSUPPORTED_METHOD(TFuture<TListJobsResult>, ListJobs, (const NScheduler::TOperationIdOrAlias&, const TListJobsOptions&));
diff --git a/yt/yt/client/scheduler/public.h b/yt/yt/client/scheduler/public.h
index d92ae73f78..bcc8c61f1a 100644
--- a/yt/yt/client/scheduler/public.h
+++ b/yt/yt/client/scheduler/public.h
@@ -8,6 +8,12 @@ namespace NYT::NScheduler {
////////////////////////////////////////////////////////////////////////////////
+YT_DEFINE_STRONG_TYPEDEF(TJobTraceId, TGuid);
+
+extern const TJobTraceId NullJobTraceId;
+
+////////////////////////////////////////////////////////////////////////////////
+
using NJobTrackerClient::TJobId;
using NJobTrackerClient::TOperationId;
diff --git a/yt/yt/client/unittests/mock/client.h b/yt/yt/client/unittests/mock/client.h
index b8217c8657..e90e6b8e71 100644
--- a/yt/yt/client/unittests/mock/client.h
+++ b/yt/yt/client/unittests/mock/client.h
@@ -626,6 +626,11 @@ public:
const TGetJobStderrOptions& options),
(override));
+ MOCK_METHOD(TFuture<std::vector<TJobTraceEvent>>, GetJobTrace, (
+ const NScheduler::TOperationIdOrAlias& operationIdOrAlias,
+ const TGetJobTraceOptions& options),
+ (override));
+
MOCK_METHOD(TFuture<TSharedRef>, GetJobFailContext, (
const NScheduler::TOperationIdOrAlias& operationIdOrAlias,
NJobTrackerClient::TJobId jobId,
diff --git a/yt/yt/core/ytree/tree_builder.h b/yt/yt/core/ytree/tree_builder.h
index 2af4d56a8d..fd959280d7 100644
--- a/yt/yt/core/ytree/tree_builder.h
+++ b/yt/yt/core/ytree/tree_builder.h
@@ -52,4 +52,3 @@ std::unique_ptr<ITreeBuilder> CreateBuilderFromFactory(INodeFactory* factory);
////////////////////////////////////////////////////////////////////////////////
} // namespace NYT::NYTree
-
diff --git a/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto b/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
index 7f3bae6c0a..0c7bc9eddc 100644
--- a/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
+++ b/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
@@ -2485,6 +2485,27 @@ message TRspGetJobStderr
////////////////////////////////////////////////////////////////////////////////
+message TReqGetJobTrace
+{
+ oneof operation_id_or_alias {
+ NYT.NProto.TGuid operation_id = 1;
+ string operation_alias = 2;
+ }
+ optional NYT.NProto.TGuid job_id = 3;
+ optional NYT.NProto.TGuid trace_id = 4;
+ optional int64 from_event_index = 5;
+ optional int64 to_event_index = 6;
+ optional int64 from_time = 7;
+ optional int64 to_time = 8;
+}
+
+message TRspGetJobTrace
+{
+ repeated TJobTraceEvent events = 1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
message TReqGetJobFailContext
{
oneof operation_id_or_alias {
@@ -3157,6 +3178,16 @@ message TListJobsResult
repeated NYT.NProto.TError errors = 6;
}
+message TJobTraceEvent
+{
+ required NYT.NProto.TGuid operation_id = 1;
+ required NYT.NProto.TGuid job_id = 2;
+ required NYT.NProto.TGuid trace_id = 3;
+ required int64 event_index = 4;
+ required string event = 5;
+ required int64 event_time = 6; // TInstant
+}
+
////////////////////////////////////////////////////////////////////////////////
message TGetFileFromCacheResult