| /** @file |
| |
| A brief file description |
| |
| @section license License |
| |
| 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. |
| */ |
| |
| /***************************************************************************** |
| * |
| * HostStatus.h - Interface to Host Status System |
| * |
| * |
| ****************************************************************************/ |
| |
| #pragma once |
| |
| #include <ctime> |
| #include <string> |
| #include <sstream> |
| #include "tscore/ink_rwlock.h" |
| #include "records/I_RecProcess.h" |
| |
| #include <unordered_map> |
| |
| // host_status stats prefix. |
| static const std::string stat_prefix = "proxy.process.host_status."; |
| |
| static const constexpr char *HostStatusNames[3] = {"HOST_STATUS_INIT", "HOST_STATUS_DOWN", "HOST_STATUS_UP"}; |
| static const constexpr char *ReasonStatus[2] = {"UP", "DOWN"}; |
| |
| struct Reason { |
| static constexpr const unsigned int ACTIVE = 0x1; |
| static constexpr const unsigned int LOCAL = 0x2; |
| static constexpr const unsigned int MANUAL = 0x4; |
| static constexpr const unsigned int SELF_DETECT = 0x8; |
| static constexpr const unsigned int ALL = 0xf; |
| |
| static constexpr const char *ACTIVE_REASON = "active"; |
| static constexpr const char *LOCAL_REASON = "local"; |
| static constexpr const char *MANUAL_REASON = "manual"; |
| static constexpr const char *SELF_DETECT_REASON = "self_detect"; |
| static constexpr const char *ALL_REASON = "all"; |
| |
| static constexpr const char *reasons[3] = {ACTIVE_REASON, LOCAL_REASON, MANUAL_REASON}; |
| |
| static bool |
| validReason(const char *reason) |
| { |
| for (const char *i : reasons) { |
| if (strcmp(i, reason) == 0) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| static unsigned int |
| getReason(const char *reason_str) |
| { |
| if (strcmp(reason_str, ACTIVE_REASON) == 0) { |
| return ACTIVE; |
| } else if (strcmp(reason_str, LOCAL_REASON) == 0) { |
| return LOCAL; |
| } else if (strcmp(reason_str, MANUAL_REASON) == 0) { |
| return MANUAL; |
| } else if (strcmp(reason_str, SELF_DETECT_REASON) == 0) { |
| return SELF_DETECT; |
| } else if (strcmp(reason_str, ALL_REASON) == 0) { |
| return ALL; |
| } |
| // default is MANUAL |
| return MANUAL; |
| } |
| }; |
| |
| // host status POD |
| struct HostStatRec { |
| TSHostStatus status; |
| unsigned int reasons; |
| // time the host was marked down for a given reason. |
| time_t active_marked_down; |
| time_t local_marked_down; |
| time_t manual_marked_down; |
| time_t self_detect_marked_down; |
| // number of seconds that the host should be marked down for a given reason. |
| unsigned int active_down_time; |
| unsigned int local_down_time; |
| unsigned int manual_down_time; |
| |
| HostStatRec(); |
| HostStatRec(std::string str); |
| HostStatRec(const HostStatRec &src) |
| { |
| status = src.status; |
| reasons = src.reasons; |
| active_marked_down = src.active_marked_down; |
| active_down_time = src.active_down_time; |
| local_marked_down = src.local_marked_down; |
| local_down_time = src.local_down_time; |
| manual_marked_down = src.manual_marked_down; |
| manual_down_time = src.manual_down_time; |
| self_detect_marked_down = src.self_detect_marked_down; |
| } |
| ~HostStatRec() {} |
| |
| HostStatRec &operator=(const HostStatRec &source) = default; |
| |
| // serialize this HostStatusRec |
| std::stringstream & |
| operator<<(std::stringstream &os) |
| { |
| unsigned int r = getReasonState(Reason::ACTIVE); |
| os << HostStatusNames[status]; |
| os << ",ACTIVE:" << ReasonStatus[r] << ":" << active_marked_down << ":" << active_down_time; |
| r = getReasonState(Reason::LOCAL); |
| os << ",LOCAL:" << ReasonStatus[r] << ":" << local_marked_down << ":" << local_down_time; |
| r = getReasonState(Reason::MANUAL); |
| os << ",MANUAL:" << ReasonStatus[r] << ":" << manual_marked_down << ":" << manual_down_time; |
| r = getReasonState(Reason::SELF_DETECT); |
| os << ",SELF_DETECT:" << ReasonStatus[r] << ":" << self_detect_marked_down; |
| |
| return os; |
| } |
| |
| // serialize a HostStatRec |
| friend std::stringstream & |
| operator<<(std::stringstream &os, HostStatRec &hs) |
| { |
| unsigned int r = hs.getReasonState(Reason::ACTIVE); |
| os << HostStatusNames[hs.status]; |
| os << ",ACTIVE:" << ReasonStatus[r] << ":" << hs.active_marked_down << ":" << hs.active_down_time; |
| r = hs.getReasonState(Reason::LOCAL); |
| os << ",LOCAL:" << ReasonStatus[r] << ":" << hs.local_marked_down << ":" << hs.local_down_time; |
| r = hs.getReasonState(Reason::MANUAL); |
| os << ",MANUAL:" << ReasonStatus[r] << ":" << hs.manual_marked_down << ":" << hs.manual_down_time; |
| r = hs.getReasonState(Reason::SELF_DETECT); |
| os << ",SELF_DETECT:" << ReasonStatus[r] << ":" << hs.self_detect_marked_down; |
| |
| return os; |
| } |
| |
| inline unsigned int |
| getReasonState(unsigned int reason) |
| { |
| unsigned int r = 0; |
| if (reasons == 0) { |
| r = 0; |
| } else if (reasons & reason) { |
| r = 1; |
| } |
| return r; |
| } |
| }; |
| |
| /** |
| * Singleton placeholder for next hop status. |
| */ |
| struct HostStatus { |
| ~HostStatus(); |
| |
| static HostStatus & |
| instance() |
| { |
| static HostStatus instance; |
| return instance; |
| } |
| void setHostStatus(const std::string_view name, const TSHostStatus status, const unsigned int down_time, |
| const unsigned int reason); |
| HostStatRec *getHostStatus(const std::string_view name); |
| void createHostStat(const std::string_view name, const char *data = nullptr); |
| void loadHostStatusFromStats(); |
| void loadRecord(std::string_view name, HostStatRec &h); |
| RecErrT getHostStat(std::string &stat_name, char *buf, unsigned int buf_len); |
| |
| private: |
| HostStatus(); |
| HostStatus(const HostStatus &obj) = delete; |
| HostStatus &operator=(HostStatus const &) = delete; |
| |
| // next hop status, key is hostname or ip string, data is HostStatRec |
| std::unordered_map<std::string, HostStatRec *> hosts_statuses; |
| |
| ink_rwlock host_status_rwlock; |
| }; |