3 * Application logger. Puts daily logs in the server's temporary directory. Log level is set in
4 * globals as $GLOBALS["log_level"] (this is customizable in the globals file).
6 * A *nix user can run the following command to see the logs:
8 * > tail -f /var/www/openemr/logs/2016_11_24_application.log
9 * 2016-11-24 20:15:07 [TRACE] \common\database\Connector - Connecting with pooled mode
10 * 2016-11-24 20:15:07 [TRACE] \common\database\Connector - Wiring up Doctrine entities
11 * 2016-11-24 20:15:07 [TRACE] \common\database\Connector - Creating connection
12 * 2016-11-24 20:15:07 [INFO] \some\other\Class - Some info message
13 * 2016-11-24 20:18:01 [WARN] \some\other\Class - Some field is missing
16 * @note Error level logs will also be sent to Apache error log.
18 * @note Application logging is sparse at the moment (will be introduced w/ the modernization project).
20 * Copyright (C) 2016 Matthew Vita <matthewvita48@gmail.com>
22 * LICENSE: This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version 2
25 * of the License, or (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>.
34 * @author Matthew Vita <matthewvita48@gmail.com>
35 * @link http://www.open-emr.org
38 namespace OpenEMR\Common\Logging
;
43 * The class that is associated with a log entry.
45 private $classContext;
48 * The fully qualified log file path.
53 * Default constructor. Only continues with instance creation
54 * if logging is enabled.
56 * @param $classContext - provided when a class uses the logger.
58 public function __construct($classContext = "UnknownClassContext")
60 if (isset($GLOBALS["log_level"]) && $GLOBALS["log_level"] !== "OFF") {
61 $this->classContext
= $classContext;
62 $this->determineLogFilePath();
67 * Sets the log file on the operating system's temporary directory. Format is:
68 * [log area] + FILE_SEP + YYYY_MM_DD_application.log
70 * On *nix, the file will be stored in /home/current_user/openemr/ (if writable). On Windows, it will
71 * be stored in C:\Users\current_user\openemr\ (if writable).
73 private function determineLogFilePath()
75 $fileName = date("Y_m_d") . "_application.log";
77 global $webserver_root;
78 $currentDir = $webserver_root;
80 $combinedLogDir = $currentDir . DIRECTORY_SEPARATOR
. $logDirName;
82 if (!is_dir($combinedLogDir)) {
83 mkdir($combinedLogDir);
86 if (is_writable($combinedLogDir)) {
87 $this->logFile
= $combinedLogDir . DIRECTORY_SEPARATOR
. $fileName;
89 error_log('Can\'t write application log file to ' . $combinedLogDir);
94 * Determines if the log level is allowed by the log level in the global
97 * Hierarchy/conditions:
98 * - TRACE (allows TRACE, DEBUG, INFO, WARN, ERROR)
99 * - DEBUG (allows DEBUG, INFO, WARN, ERROR)
100 * - INFO (allows INFO, WARN, ERROR)
101 * - WARN (allows WARN, ERROR)
102 * - ERROR (allows ERROR)
105 * @param $level the incoming log level
106 * @return boolean that represents if log entry should be made
108 private function isLogLevelInDesiredHierarchy($level)
110 if (empty($GLOBALS["log_level"]) ||
$GLOBALS["log_level"] === "OFF") {
114 if ($GLOBALS["log_level"] === "TRACE") {
116 } else if ($GLOBALS["log_level"] === "DEBUG" && in_array($level, array("DEBUG", "INFO", "WARN", "ERROR"))) {
118 } else if ($GLOBALS["log_level"] === "INFO" && in_array($level, array("INFO", "WARN", "ERROR"))) {
120 } else if ($GLOBALS["log_level"] === "WARN" && in_array($level, array("WARN", "ERROR"))) {
122 } else if ($GLOBALS["log_level"] === "ERROR" && $level === "ERROR") {
130 * Used for informational messages of the application.
132 * @param $message - the log message
134 public function info($message)
136 $this->log($message, "INFO");
140 * Used by developers that wish to expose information that is
141 * notable for developers.
143 * @param $message - the log message
145 public function debug($message)
147 $this->log($message, "DEBUG");
151 * Used by developers that wish to expose information that is
152 * notable for developers. Note this is more "noisy" than debug.
154 * @param $message - the log message
156 public function trace($message)
158 $this->log($message, "TRACE");
162 * Used for in case of harmful conditions.
164 * @param $message - the log message
166 public function warn($message)
168 $this->log($message, "WARN");
172 * Used for in case an error occurs and the application might continue running.
174 * @param $message - the log message
176 public function error($message)
178 $this->log($message, "ERROR");
182 * Writes the entry to the log file. If the level is type "error", the message
183 * will additionally go to the Apache error log.
185 * @param $message - the log message
186 * @param $type - the log type
188 private function log($message, $type)
190 if ($this->isLogLevelInDesiredHierarchy($type) && !empty($this->logFile
)) {
191 $logEntry = date("Y-m-d H:i:s") . " [" . $type . "] " . $this->classContext
. " - " . $message;
193 file_put_contents($this->logFile
, $logEntry.PHP_EOL
, FILE_APPEND | LOCK_EX
);
195 if ($type === "ERROR") {