1 /**
2  * Copyright © 2020 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "sensor_monitoring.hpp"
18 
19 #include "action_environment.hpp"
20 #include "action_utils.hpp"
21 #include "chassis.hpp"
22 #include "device.hpp"
23 #include "error_logging_utils.hpp"
24 #include "exception_utils.hpp"
25 #include "rail.hpp"
26 #include "sensors.hpp"
27 #include "system.hpp"
28 
29 #include <exception>
30 
31 namespace phosphor::power::regulators
32 {
33 
34 /**
35  * Maximum number of consecutive errors before an error log entry is created.
36  * This provides "de-glitching" to ignore transient hardware problems.
37  *
38  * Also the maximum number of consecutive errors that will be logged to the
39  * journal.
40  */
41 constexpr unsigned short maxErrorCount{6};
42 
43 void SensorMonitoring::execute(Services& services, System& system,
44                                Chassis& chassis, Device& device, Rail& rail)
45 {
46     // Notify sensors service that monitoring is starting for this rail
47     Sensors& sensors = services.getSensors();
48     sensors.startRail(rail.getID(), device.getFRU(),
49                       chassis.getInventoryPath());
50 
51     // Read all sensors defined for this rail
52     try
53     {
54         // Create ActionEnvironment
55         ActionEnvironment environment{system.getIDMap(), device.getID(),
56                                       services};
57 
58         // Execute the actions
59         action_utils::execute(actions, environment);
60 
61         // Reset consecutive error count since sensors were read successfully
62         errorCount = 0;
63     }
64     catch (const std::exception& e)
65     {
66         // If we haven't hit the maximum consecutive error count yet
67         if (errorCount < maxErrorCount)
68         {
69             // Log error messages in journal
70             services.getJournal().logError(exception_utils::getMessages(e));
71             services.getJournal().logError(
72                 "Unable to monitor sensors for rail " + rail.getID());
73 
74             // Increment error count.  If now at max, create error log entry.
75             if (++errorCount >= maxErrorCount)
76             {
77                 error_logging_utils::logError(std::current_exception(),
78                                               Entry::Level::Warning, services,
79                                               errorHistory);
80             }
81         }
82     }
83 
84     // Notify sensors service that monitoring has ended for this rail
85     bool errorOccurred = (errorCount > 0);
86     sensors.endRail(errorOccurred);
87 }
88 
89 } // namespace phosphor::power::regulators
90