| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #pragma once |
| |
| #include "rpc/thrift-server.h" |
| #include "util/metrics-fwd.h" |
| #include "util/internal-queue.h" |
| |
| #include <thrift/TProcessor.h> |
| #include <boost/unordered_map.hpp> |
| |
| #include <rapidjson/document.h> |
| |
| namespace impala { |
| |
| class MetricGroup; |
| class RpcMgr; |
| class Webserver; |
| |
| /// An RpcEventHandler is called every time an Rpc is started and completed. There is at |
| /// most one RpcEventHandler per ThriftServer. When an Rpc is started, getContext() creates |
| /// an InvocationContext recording the current time and other metadata for that invocation. |
| class RpcEventHandler : public apache::thrift::TProcessorEventHandler { |
| public: |
| RpcEventHandler(const std::string& server_name, MetricGroup* metrics); |
| |
| /// From TProcessorEventHandler, called initially when an Rpc is invoked. Returns an |
| /// InvocationContext*. 'server_context' is a per-connection context object. For our |
| /// Thrift servers, it is always a ThriftServer::ConnectionContext*. |
| virtual void* getContext(const char* fn_name, void* server_context); |
| |
| /// From TProcessorEventHandler, called after all bytes were written to the calling |
| /// client. 'ctx' is the context returned by getContext(), which is an |
| /// InvocationContext*. |
| virtual void postWrite(void* ctx, const char* fn_name, uint32_t bytes); |
| |
| /// Helper method to dump all per-method summaries to Json |
| /// Json produced looks like: |
| /// { |
| /// "name": "beeswax", |
| /// "methods": [ |
| /// { |
| /// "name": "BeeswaxService.get_state", |
| /// "summary": " count: 1, last: 0, min: 0, max: 0, mean: 0, stddev: 0", |
| /// "in_flight": 0 |
| /// }, |
| /// { |
| /// "name": "BeeswaxService.query", |
| /// "summary": " count: 1, last: 293, min: 293, max: 293, mean: 293, stddev: 0", |
| /// "in_flight": 0 |
| /// }, |
| /// ] |
| /// } |
| void ToJson(rapidjson::Value* server, rapidjson::Document* document); |
| |
| /// Resets the statistics for a single method |
| void Reset(const std::string& method_name); |
| |
| /// Resets the statistics for all methods |
| void ResetAll(); |
| |
| std::string server_name() const { return server_name_; } |
| |
| private: |
| /// Per-method descriptor |
| struct MethodDescriptor { |
| /// Name of the method |
| std::string name; |
| |
| /// Distribution of the time taken to process this RPC. |
| HistogramMetric* processing_time_distribution; |
| |
| /// Number of invocations in flight |
| AtomicInt32 num_in_flight; |
| }; |
| |
| /// Map from method name to descriptor |
| typedef boost::unordered_map<std::string, MethodDescriptor*> MethodMap; |
| |
| /// Created per-Rpc invocation |
| struct InvocationContext { |
| /// Monotonic milliseconds (typically boot time) when the call started. |
| const int64_t start_time_ms; |
| |
| /// Per-connection information, owned by ThriftServer. The lifetime of this struct is |
| /// tied to the lifetime of the connection, which is guaranteed to be longer than the |
| /// rpc lifetime. |
| const ThriftServer::ConnectionContext* cnxn_ctx; |
| |
| /// Pointer to parent MethodDescriptor, to save a lookup on deletion |
| MethodDescriptor* method_descriptor; |
| |
| InvocationContext(int64_t start_time, const ThriftServer::ConnectionContext* cnxn_ctx, |
| MethodDescriptor* descriptor) |
| : start_time_ms(start_time), cnxn_ctx(cnxn_ctx), method_descriptor(descriptor) { } |
| }; |
| |
| /// Protects method_map_ and rpc_counter_ |
| std::mutex method_map_lock_; |
| |
| /// Map of all methods, populated lazily as they are invoked for the first time. |
| MethodMap method_map_; |
| |
| /// Name of the server that we listen for events from. |
| std::string server_name_; |
| |
| /// Metrics subsystem access |
| MetricGroup* metrics_; |
| |
| }; |
| |
| /// Initialises rpc event tracing, must be called before any RpcEventHandlers are created. |
| void InitRpcEventTracing(Webserver* webserver, RpcMgr* = nullptr); |
| |
| } |