Python: Model logging from the logging module

This commit is contained in:
Rasmus Wriedt Larsen
2021-06-25 14:20:23 +02:00
parent c05e375401
commit 68cfeb0b5c
2 changed files with 80 additions and 23 deletions

View File

@@ -1255,6 +1255,63 @@ private module Stdlib {
result = this.getArgByName("string")
}
}
// ---------------------------------------------------------------------------
// logging
// ---------------------------------------------------------------------------
/**
* Provides models for the `logging.Logger` class and subclasses.
*
* See https://docs.python.org/3.9/library/logging.html#logging.Logger.
*/
module Logger {
/** Gets a reference to the `logging.Logger` class or any subclass. */
API::Node subclassRef() {
result = API::moduleImport("logging").getMember("Logger").getASubclass*()
}
/** Gets a reference to an instance of `logging.Logger` or any subclass. */
API::Node instance() {
result = subclassRef().getReturn()
or
result = API::moduleImport("logging").getMember("root")
or
result = API::moduleImport("logging").getMember("getLogger").getReturn()
}
}
/**
* A call to one of the logging methods from `logging` or on a `logging.Logger`
* subclass.
*
* See:
* - https://docs.python.org/3.9/library/logging.html#logging.debug
* - https://docs.python.org/3.9/library/logging.html#logging.Logger.debug
*/
class LoggerLogCall extends Logging::Range, DataFlow::CallCfgNode {
/** The argument-index where the message is passed. */
int msgIndex;
LoggerLogCall() {
exists(string method |
method in ["critical", "fatal", "error", "warning", "warn", "info", "debug", "exception"] and
msgIndex = 0
or
method = "log" and
msgIndex = 1
|
this = Logger::instance().getMember(method).getACall()
or
this = API::moduleImport("logging").getMember(method).getACall()
)
}
override DataFlow::Node getAnInput() {
result = this.getArgByName("msg")
or
result = this.getArg(any(int i | i >= msgIndex))
}
}
}
// ---------------------------------------------------------------------------

View File

@@ -8,38 +8,38 @@ msg = "foo %s"
LOGGER = logging.getLogger("LOGGER")
logging.info(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
logging.info(msg="hello") # $ MISSING: loggingInput="hello"
logging.info(msg, password) # $ loggingInput=msg loggingInput=password
logging.info(msg="hello") # $ loggingInput="hello"
logging.log(logging.INFO, msg, password) # $ MISSING: loggingInput=msg loggingInput=password
LOGGER.log(logging.INFO, msg, password) # $ MISSING: loggingInput=msg loggingInput=password
logging.log(logging.INFO, msg, password) # $ loggingInput=msg loggingInput=password
LOGGER.log(logging.INFO, msg, password) # $ loggingInput=msg loggingInput=password
logging.root.info(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
logging.root.info(msg, password) # $ loggingInput=msg loggingInput=password
# test of all levels
logging.critical(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
logging.fatal(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
logging.error(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
logging.warning(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
logging.warn(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
logging.info(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
logging.debug(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
logging.exception(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
logging.critical(msg, password) # $ loggingInput=msg loggingInput=password
logging.fatal(msg, password) # $ loggingInput=msg loggingInput=password
logging.error(msg, password) # $ loggingInput=msg loggingInput=password
logging.warning(msg, password) # $ loggingInput=msg loggingInput=password
logging.warn(msg, password) # $ loggingInput=msg loggingInput=password
logging.info(msg, password) # $ loggingInput=msg loggingInput=password
logging.debug(msg, password) # $ loggingInput=msg loggingInput=password
logging.exception(msg, password) # $ loggingInput=msg loggingInput=password
LOGGER.critical(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
LOGGER.fatal(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
LOGGER.error(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
LOGGER.warning(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
LOGGER.warn(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
LOGGER.info(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
LOGGER.debug(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
LOGGER.exception(msg, password) # $ MISSING: loggingInput=msg loggingInput=password
LOGGER.critical(msg, password) # $ loggingInput=msg loggingInput=password
LOGGER.fatal(msg, password) # $ loggingInput=msg loggingInput=password
LOGGER.error(msg, password) # $ loggingInput=msg loggingInput=password
LOGGER.warning(msg, password) # $ loggingInput=msg loggingInput=password
LOGGER.warn(msg, password) # $ loggingInput=msg loggingInput=password
LOGGER.info(msg, password) # $ loggingInput=msg loggingInput=password
LOGGER.debug(msg, password) # $ loggingInput=msg loggingInput=password
LOGGER.exception(msg, password) # $ loggingInput=msg loggingInput=password
# not sure how to make these print anything, but just to show that it works
logging.Logger("foo").info("hello") # $ MISSING: loggingInput="hello"
logging.Logger("foo").info("hello") # $ loggingInput="hello"
class MyLogger(logging.Logger):
pass
MyLogger("bar").info("hello") # $ MISSING: loggingInput="hello"
MyLogger("bar").info("hello") # $ loggingInput="hello"