1 /** @file 2 3 A brief file description 4 5 @section license License 6 7 Licensed to the Apache Software Foundation (ASF) under one 8 or more contributor license agreements. See the NOTICE file 9 distributed with this work for additional information 10 regarding copyright ownership. The ASF licenses this file 11 to you under the Apache License, Version 2.0 (the 12 "License"); you may not use this file except in compliance 13 with the License. You may obtain a copy of the License at 14 15 http://www.apache.org/licenses/LICENSE-2.0 16 17 Unless required by applicable law or agreed to in writing, software 18 distributed under the License is distributed on an "AS IS" BASIS, 19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 See the License for the specific language governing permissions and 21 limitations under the License. 22 */ 23 24 /***************************************************************************** 25 * 26 * HostStatus.h - Interface to Host Status System 27 * 28 * 29 ****************************************************************************/ 30 31 #pragma once 32 33 #include <ctime> 34 #include <string> 35 #include <sstream> 36 #include "tscore/ink_rwlock.h" 37 #include "records/P_RecProcess.h" 38 39 #include <unordered_map> 40 41 // host_status stats prefix. 42 static const std::string stat_prefix = "proxy.process.host_status."; 43 44 enum HostStatus_t { 45 HOST_STATUS_INIT, 46 HOST_STATUS_DOWN, 47 HOST_STATUS_UP, 48 }; 49 50 static const constexpr char *HostStatusNames[3] = {"HOST_STATUS_INIT", "HOST_STATUS_DOWN", "HOST_STATUS_UP"}; 51 static const constexpr char *ReasonStatus[2] = {"UP", "DOWN"}; 52 53 struct Reason { 54 static constexpr const unsigned int ACTIVE = 0x1; 55 static constexpr const unsigned int LOCAL = 0x2; 56 static constexpr const unsigned int MANUAL = 0x4; 57 static constexpr const unsigned int SELF_DETECT = 0x8; 58 static constexpr const unsigned int ALL = 0xf; 59 60 static constexpr const char *ACTIVE_REASON = "active"; 61 static constexpr const char *LOCAL_REASON = "local"; 62 static constexpr const char *MANUAL_REASON = "manual"; 63 static constexpr const char *SELF_DETECT_REASON = "self_detect"; 64 static constexpr const char *ALL_REASON = "all"; 65 66 static constexpr const char *reasons[3] = {ACTIVE_REASON, LOCAL_REASON, MANUAL_REASON}; 67 68 static bool validReasonReason69 validReason(const char *reason) 70 { 71 for (const char *i : reasons) { 72 if (strcmp(i, reason) == 0) { 73 return true; 74 } 75 } 76 return false; 77 } 78 79 static unsigned int getReasonReason80 getReason(const char *reason_str) 81 { 82 if (strcmp(reason_str, ACTIVE_REASON) == 0) { 83 return ACTIVE; 84 } else if (strcmp(reason_str, LOCAL_REASON) == 0) { 85 return LOCAL; 86 } else if (strcmp(reason_str, MANUAL_REASON) == 0) { 87 return MANUAL; 88 } else if (strcmp(reason_str, SELF_DETECT_REASON) == 0) { 89 return SELF_DETECT; 90 } else if (strcmp(reason_str, ALL_REASON) == 0) { 91 return ALL; 92 } 93 // default is MANUAL 94 return MANUAL; 95 } 96 }; 97 98 // host status POD 99 struct HostStatRec { 100 HostStatus_t status; 101 unsigned int reasons; 102 // time the host was marked down for a given reason. 103 time_t active_marked_down; 104 time_t local_marked_down; 105 time_t manual_marked_down; 106 time_t self_detect_marked_down; 107 // number of seconds that the host should be marked down for a given reason. 108 unsigned int active_down_time; 109 unsigned int local_down_time; 110 unsigned int manual_down_time; 111 112 HostStatRec(); 113 HostStatRec(std::string str); HostStatRecHostStatRec114 HostStatRec(const HostStatRec &src) 115 { 116 status = src.status; 117 reasons = src.reasons; 118 active_marked_down = src.active_marked_down; 119 active_down_time = src.active_down_time; 120 local_marked_down = src.local_marked_down; 121 local_down_time = src.local_down_time; 122 manual_marked_down = src.manual_marked_down; 123 manual_down_time = src.manual_down_time; 124 self_detect_marked_down = src.self_detect_marked_down; 125 } ~HostStatRecHostStatRec126 ~HostStatRec() {} 127 128 HostStatRec &operator=(const HostStatRec &source) = default; 129 130 // serialize this HostStatusRec 131 std::stringstream & 132 operator<<(std::stringstream &os) 133 { 134 unsigned int r = getReasonState(Reason::ACTIVE); 135 os << HostStatusNames[status]; 136 os << ",ACTIVE:" << ReasonStatus[r] << ":" << active_marked_down << ":" << active_down_time; 137 r = getReasonState(Reason::LOCAL); 138 os << ",LOCAL:" << ReasonStatus[r] << ":" << local_marked_down << ":" << local_down_time; 139 r = getReasonState(Reason::MANUAL); 140 os << ",MANUAL:" << ReasonStatus[r] << ":" << manual_marked_down << ":" << manual_down_time; 141 r = getReasonState(Reason::SELF_DETECT); 142 os << ",SELF_DETECT:" << ReasonStatus[r] << ":" << self_detect_marked_down; 143 144 return os; 145 } 146 147 // serialize a HostStatRec 148 friend std::stringstream & 149 operator<<(std::stringstream &os, HostStatRec &hs) 150 { 151 unsigned int r = hs.getReasonState(Reason::ACTIVE); 152 os << HostStatusNames[hs.status]; 153 os << ",ACTIVE:" << ReasonStatus[r] << ":" << hs.active_marked_down << ":" << hs.active_down_time; 154 r = hs.getReasonState(Reason::LOCAL); 155 os << ",LOCAL:" << ReasonStatus[r] << ":" << hs.local_marked_down << ":" << hs.local_down_time; 156 r = hs.getReasonState(Reason::MANUAL); 157 os << ",MANUAL:" << ReasonStatus[r] << ":" << hs.manual_marked_down << ":" << hs.manual_down_time; 158 r = hs.getReasonState(Reason::SELF_DETECT); 159 os << ",SELF_DETECT:" << ReasonStatus[r] << ":" << hs.self_detect_marked_down; 160 161 return os; 162 } 163 164 inline unsigned int getReasonStateHostStatRec165 getReasonState(unsigned int reason) 166 { 167 unsigned int r = 0; 168 if (reasons == 0) { 169 r = 0; 170 } else if (reasons & reason) { 171 r = 1; 172 } 173 return r; 174 } 175 }; 176 177 /** 178 * Singleton placeholder for next hop status. 179 */ 180 struct HostStatus { 181 ~HostStatus(); 182 183 static HostStatus & instanceHostStatus184 instance() 185 { 186 static HostStatus instance; 187 return instance; 188 } 189 void setHostStatus(const char *name, const HostStatus_t status, const unsigned int down_time, const unsigned int reason); 190 HostStatRec *getHostStatus(const char *name); 191 void createHostStat(const char *name, const char *data = nullptr); 192 void loadHostStatusFromStats(); 193 void loadRecord(std::string &name, HostStatRec &h); 194 RecErrT getHostStat(std::string &stat_name, char *buf, unsigned int buf_len); 195 196 private: 197 HostStatus(); 198 HostStatus(const HostStatus &obj) = delete; 199 HostStatus &operator=(HostStatus const &) = delete; 200 201 // next hop status, key is hostname or ip string, data is HostStatRec 202 std::unordered_map<std::string, HostStatRec *> hosts_statuses; 203 204 ink_rwlock host_status_rwlock; 205 }; 206