[WIP] [EVENT] basic function and defination#9612
[WIP] [EVENT] basic function and defination#9612Basasuya wants to merge 1 commit intoray-project:masterfrom
Conversation
|
Can one of the admins verify this patch? |
rkooo567
left a comment
There was a problem hiding this comment.
I added a few comments that are for discussion!
| << Event_SourceType_Name(event.source_type()) + separator_ | ||
| << event.source_hostname() + separator_ | ||
| << std::to_string(event.source_pid()) + separator_ | ||
| << Event_Severity_Name(event.severity()) + separator_ |
There was a problem hiding this comment.
Why don't we make it like json format, so that it is easy to parse?
There was a problem hiding this comment.
First, this function is a virtual function that can be inherited. BTW, If we intend to write files, The JSON format will write more bytes than the current implementation. In our internal system, the monitor backend prefers to read the separator to analyze the event file.
There was a problem hiding this comment.
We should just use JSON as a standard format instead of inventing our own. This will make it easier for OSS users to integrate with and is similar to other structured logging formats (e.g., https://github.com/uber-go/zap)
There was a problem hiding this comment.
We should not use the format that is specific for Ant's internal systems in OSS. It should be the format that is more generally used by the industry. (I guess you guys can have a separate implementation to use this separator).
There was a problem hiding this comment.
@edoakes I think the example of zap is convinced for us. We plan to change to the JSON format.
I think there is a small question about If the user prints multiple lines for example:
RAY_EVENT(INFO, "label") << "process 1\nprocess 2\nprocess3"
How do we solve this situation, should we print multiple lines?
| return result.str(); | ||
| } | ||
|
|
||
| void RayEventContext::SetEventContext(rpc::Event_SourceType source_type, |
There was a problem hiding this comment.
cc @edoakes I think it is better having more flexible map labels rather than 4 hardcoded labels. The idea is we always have global level labels per process (like these 4), and support additional global level labels or custom labels at each event.
There was a problem hiding this comment.
we prepare to add a map<string, string> to store the custom labels
maybe the user can use RayEventContext::Instance()::SetCustomContext(std::string, std::string)
I will modify this week.
There was a problem hiding this comment.
Yes I would much prefer to just have a map of labels. We can autopopulate a few of them but I don't see a reason to have these hardcoded.
| bool IsEmpty() { return reporter_map_.empty(); } | ||
|
|
||
| void Publish(rpc::Event &event) { | ||
| for (const auto &element : reporter_map_) { |
There was a problem hiding this comment.
Why do you define this in the header?
There was a problem hiding this comment.
OK. I will fix it this week.
| return *this; | ||
| } | ||
|
|
||
| static void ReportEvent(std::string severity, std::string label, std::string message) { |
There was a problem hiding this comment.
Is it the best practice to just send messages for events? In this case, I really cannot find differences between logs and events except that the cardinality is lower. I had some impression that we should somehow pre-define events with some description, so that we can prevent using tons of events in the repo? Idk what's the best practice in the industry, so let me know what you think about this.
| ":sha256", | ||
| "@boost//:asio", | ||
| "@boost//:filesystem", | ||
| ":event_cc_proto", |
There was a problem hiding this comment.
":event_cc_proto",
":sha256",
"@boost//:asio",
"@boost//:asio",
"@boost//:filesystem",
| RAY_CHECK(rpc::Event_SourceType_IsValid(RayEventContext::Instance().GetSourceType())); | ||
| RAY_CHECK(rpc::Event_Severity_IsValid(severity_)); |
|
|
||
| std::string event_id_buffer = std::string(18, ' '); | ||
| FillRandom(&event_id_buffer); | ||
| constexpr char hex[] = "0123456789abcdef"; |
There was a problem hiding this comment.
It could reuse util function rather than duplicated implementation.
There was a problem hiding this comment.
In the internal system, we use the StringToHex function. But I find there is no function in the OSS.
There was a problem hiding this comment.
In the internal system, we use the StringToHex function. But I find there is no function in the OSS.
You can put these utils function in util.h as well, which makes sense for ray overall.
| // 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. | ||
| #ifndef RAY_EVENT_H_ |
|
|
||
| class EventManager { | ||
| public: | ||
| static EventManager &Instance() { |
There was a problem hiding this comment.
There is no such shutdown or deconstrutor for EventManager.
We'd better use smart pointer for singleton instance so sources or somethings like could be released after process halted, and we can reset it in-fly.
There was a problem hiding this comment.
use clearReporters function, we can shut down the EventManager. Maybe I should modify the clearReporters to shutdown function.
| std::string task_id_ = ""; | ||
| rpc::Event_SourceType source_type_ = rpc::Event_SourceType::Event_SourceType_COMMON; | ||
| std::string source_hostname_ = boost::asio::ip::host_name(); | ||
| int32_t source_pid_ = getpid(); |
| std::unordered_map<std::string, std::shared_ptr<LogBasedEventReporter>> reporter_map_; | ||
| }; | ||
|
|
||
| class RayEventContext { |
There was a problem hiding this comment.
Make it finalized with class RayEventContext final.
|
|
||
| inline void SetTaskID(std::string task_id) { task_id_ = task_id; } | ||
|
|
||
| inline std::string GetJobID() { return job_id_; } |
There was a problem hiding this comment.
inline const std::string& GetJobID() const { return job_id_; }
same issue in other Get/Set.
|
Test FAILed. |
| return result.str(); | ||
| } | ||
|
|
||
| void RayEventContext::SetEventContext(rpc::Event_SourceType source_type, |
There was a problem hiding this comment.
Yes I would much prefer to just have a map of labels. We can autopopulate a few of them but I don't see a reason to have these hardcoded.
| << Event_SourceType_Name(event.source_type()) + separator_ | ||
| << event.source_hostname() + separator_ | ||
| << std::to_string(event.source_pid()) + separator_ | ||
| << Event_Severity_Name(event.severity()) + separator_ |
There was a problem hiding this comment.
We should just use JSON as a standard format instead of inventing our own. This will make it easier for OSS users to integrate with and is similar to other structured logging formats (e.g., https://github.com/uber-go/zap)
| inline void SetJobID(std::string job_id) { job_id_ = job_id; } | ||
|
|
||
| inline void SetNodeID(std::string node_id) { node_id_ = node_id; } | ||
|
|
||
| inline void SetTaskID(std::string task_id) { task_id_ = task_id; } | ||
|
|
||
| inline std::string GetJobID() { return job_id_; } | ||
|
|
||
| inline std::string GetNodeID() { return node_id_; } | ||
|
|
||
| inline std::string GetTaskID() { return task_id_; } | ||
|
|
||
| inline rpc::Event_SourceType GetSourceType() { return source_type_; } | ||
|
|
||
| inline std::string GetSourceHostname() { return source_hostname_; } | ||
|
|
||
| inline int32_t GetSourcePid() { return source_pid_; } |
There was a problem hiding this comment.
Why do we need all of these getters and setters instead of just a simple constructor?
Why are these changes needed?
Related issue number
Checks
scripts/format.shto lint the changes in this PR.