1 /*  $Id: ns_alert.cpp 601644 2020-02-11 19:47:28Z satskyse $
2  * ===========================================================================
3  *
4  *                            PUBLIC DOMAIN NOTICE
5  *               National Center for Biotechnology Information
6  *
7  *  This software/database is a "United States Government Work" under the
8  *  terms of the United States Copyright Act.  It was written as part of
9  *  the author's official duties as a United States Government employee and
10  *  thus cannot be copyrighted.  This software/database is freely available
11  *  to the public for use. The National Library of Medicine and the U.S.
12  *  Government have not placed any restriction on its use or reproduction.
13  *
14  *  Although all reasonable efforts have been taken to ensure the accuracy
15  *  and reliability of the software and data, the NLM and the U.S.
16  *  Government do not and cannot warrant the performance or results that
17  *  may be obtained by using this software or data. The NLM and the U.S.
18  *  Government disclaim all warranties, express or implied, including
19  *  warranties of performance, merchantability or fitness for any particular
20  *  purpose.
21  *
22  *  Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors:  Sergey Satskiy
27  *
28  * File Description: NeSchedule affinity registry
29  *
30  */
31 #include <ncbi_pch.hpp>
32 #include <corelib/ncbistd.hpp>
33 
34 #include "ns_alert.hpp"
35 
36 
37 BEGIN_NCBI_SCOPE
38 
39 struct AlertToId
40 {
41     enum EAlertType     type;
42     string              id;
43 };
44 
45 
46 const AlertToId     alertToIdMap[] = {
47     { eStartupConfig,       "StartupConfig" },
48     { eReconfigure,         "Reconfigure" },
49     { ePidFile,             "PidFile" },
50     { eStartAfterCrash,     "StartedAfterCrash" },
51     { eAccess,              "AccessDenied" },
52     { eConfigOutOfSync,     "ConfigOutOfSync" },
53     { eReinit,              "Reinit" },
54     { eNoDump,              "NoDump" },
55     { eDumpError,           "DumpError" },
56     { eMaxQueues,           "MaxQueues" },
57     { eDumpLoadError,       "DumpLoadError" },
58     { eDumpSpaceError,      "DumpSpaceError" },
59     { eDataDirRemoveError,  "DataDirRemoveError" } };
60 const size_t        alertToIdMapSize = sizeof(alertToIdMap) / sizeof(AlertToId);
61 
62 
63 
Serialize(void) const64 string SNSAlertAttributes::Serialize(void) const
65 {
66     string      acknowledged;
67 
68     if (m_AcknowledgedTimestamp == kTimeZero)
69         acknowledged = "n/a";
70     else
71         acknowledged = NS_FormatPreciseTime(m_AcknowledgedTimestamp);
72 
73     return "OK:last_detected_time: " +
74                         NS_FormatPreciseTime(m_LastDetectedTimestamp) + "\n"
75            "OK:acknowledged_time: " + acknowledged + "\n"
76            "OK:on: " + NStr::BoolToString(m_On) + "\n"
77            "OK:count: " + to_string(m_Count) + "\n"
78            "OK:count_since_acknowledge: " + to_string(m_CountSinceAck) + "\n"
79            "OK:user: " + m_User + "\n"
80            "OK:message: \"" + NStr::PrintableString(m_Message) + "\"";
81 }
82 
83 
Register(enum EAlertType alert_type,const string & message)84 void CNSAlerts::Register(enum EAlertType  alert_type,
85                          const string &   message)
86 {
87     map< enum EAlertType,
88          SNSAlertAttributes >::iterator     found;
89     CFastMutexGuard                         guard(m_Lock);
90 
91     found = m_Alerts.find(alert_type);
92     if (found != m_Alerts.end()) {
93         // Alert has already been there
94         found->second.m_LastDetectedTimestamp = CNSPreciseTime::Current();
95         found->second.m_On = true;
96         ++found->second.m_Count;
97         ++found->second.m_CountSinceAck;
98         found->second.m_Message = message;
99         return;
100     }
101 
102     // Brand new alert
103     SNSAlertAttributes      attrs;
104     attrs.m_Message = message;
105     m_Alerts[alert_type] = attrs;
106 }
107 
108 
Acknowledge(const string & alert_id,const string & user)109 enum EAlertAckResult CNSAlerts::Acknowledge(const string &  alert_id,
110                                             const string &  user)
111 {
112     EAlertType  type = x_IdToType(alert_id);
113     if (type == eUnknown)
114         return eNotFound;
115 
116     return Acknowledge(type, user);
117 }
118 
119 
Acknowledge(enum EAlertType alert_type,const string & user)120 enum EAlertAckResult CNSAlerts::Acknowledge(enum EAlertType alert_type,
121                                             const string &  user)
122 {
123     map< enum EAlertType,
124          SNSAlertAttributes >::iterator     found;
125     CFastMutexGuard                         guard(m_Lock);
126 
127     found = m_Alerts.find(alert_type);
128     if (found == m_Alerts.end())
129         return eNotFound;
130 
131     if (!found->second.m_On)
132         return eAlreadyAcknowledged;
133 
134     found->second.m_AcknowledgedTimestamp = CNSPreciseTime::Current();
135     found->second.m_On = false;
136     found->second.m_User = user;
137     found->second.m_CountSinceAck = 0;
138     return eAcknowledged;
139 }
140 
141 
x_IdToType(const string & alert_id) const142 enum EAlertType CNSAlerts::x_IdToType(const string &  alert_id) const
143 {
144     for (size_t  k = 0; k < alertToIdMapSize; ++k) {
145         if (NStr::CompareNocase(alert_id, alertToIdMap[k].id) == 0)
146             return alertToIdMap[k].type;
147     }
148     return eUnknown;
149 }
150 
151 
x_TypeToId(enum EAlertType type) const152 string CNSAlerts::x_TypeToId(enum EAlertType  type) const
153 {
154     for (size_t  k = 0; k < alertToIdMapSize; ++k) {
155         if (alertToIdMap[k].type == type)
156             return alertToIdMap[k].id;
157     }
158     return "unknown";
159 }
160 
161 
162 // Provides the alerts which are on at the moment.
163 // It is a url encoded format
GetURLEncoded(void) const164 string CNSAlerts::GetURLEncoded(void) const
165 {
166     string                                      result;
167     map< enum EAlertType,
168          SNSAlertAttributes >::const_iterator   k;
169     CFastMutexGuard                             guard(m_Lock);
170 
171     for (k = m_Alerts.begin(); k != m_Alerts.end(); ++k) {
172         if (!result.empty())
173             result += "&";
174         result += "alert_" + x_TypeToId(k->first) + "=";
175         if (!k->second.m_On)
176             result += "-";
177         result += to_string(k->second.m_CountSinceAck) +
178                   "/" + to_string(k->second.m_Count);
179     }
180     return result;
181 }
182 
183 
184 // Provides the alerts for the STAT ALERTS command
Serialize(void) const185 string CNSAlerts::Serialize(void) const
186 {
187     string                                      result;
188     map< enum EAlertType,
189          SNSAlertAttributes >::const_iterator   k;
190     CFastMutexGuard                             guard(m_Lock);
191 
192     for (k = m_Alerts.begin(); k != m_Alerts.end(); ++k) {
193         if (!result.empty())
194             result += "\n";
195         result += "OK:[alert " + x_TypeToId(k->first) + "]\n" +
196                   k->second.Serialize();
197     }
198     return result;
199 }
200 
201 
202 END_NCBI_SCOPE
203 
204