diff --git a/doc/source/guidelines/logging.rst b/doc/source/guidelines/logging.rst
index 8154082e3..37e2809f8 100644
--- a/doc/source/guidelines/logging.rst
+++ b/doc/source/guidelines/logging.rst
@@ -1,43 +1,43 @@
Logging Guidelines
##################
-This section describes several guidelines for logging in PyAnsys
-libraries. These guidelines are best practices discovered through
-implementing logging services and modules within PyAnsys
-libraries. Suggestions and improvements are welcome.
-External resources also describe `basic `__
-and `advanced `__ technics.
+This section describes several guidelines for logging in PyAnsys libraries.
+These guidelines are best practices discovered through implementing logging
+services and modules within PyAnsys libraries. Suggestions and improvements are
+welcome.
+External resources also describe `basic
+`__ and `advanced
+`__ technics.
Description and usage
=====================
-Logging helps to track events occurring in the application. For each of them a log record
-is created. It contains a detailed set of information about the current application operation.
-Whenever an information must be exposed, displayed and shared, logging is the
-way to do it.
-It is destinated to both the users and the application developers.
-It can serve several purposes:
+Logging helps to track events occurring in the application. For each of them a
+log record is created. It contains a detailed set of information about the
+current application operation. Whenever an information must be exposed,
+displayed and shared, logging is the way to do it.
+It is destinated to both the users and the application developers. It can serve
+several purposes:
- extract some valuable data for the final users to know the status of their work.
- track the progress and the course of the application usage.
- provide the developer with as much information as possible if an issue happens.
-The message logged can contain generic information or embed data specific
-to the current session.
+The message logged can contain generic information or embed data specific to the
+current session.
Message content is associated to a level of severity (info, warning, error...).
Generally, this degree of significance indicates the recipient of the message.
-An info message is directed to the user while a debug message is useful for
-the developer itself.
+An info message is directed to the user while a debug message is useful for the
+developer itself.
Logging in PyAnsys Libraries
============================
-The logging capabilities in PyAnsys libraries should be built upon the
-`standard logging `__
-library. PyAnsys libries should not to replace this library, rather provide
-a standardized way to interact between the built-in :mod:`logging`
-library and ``PyAnsys`` libraries.
+The logging capabilities in PyAnsys libraries should be built upon the `standard
+logging `__ library. PyAnsys
+libries should not to replace this library, rather provide a standardized way to
+interact between the built-in :mod:`logging` library and ``PyAnsys`` libraries.
Logging Best Practices
@@ -45,18 +45,19 @@ Logging Best Practices
Avoid printing to the console
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A common habit while prototyping a new feature is to print message into the command line executable.
-Instead of using the common ``Print()`` method, it is advised to use a ``StreamHandler`` and redirect its content.
-Indeed that will allow to filter messages based on their level and apply properly the formatter.
-To do so, a boolean argument can be added in the initializer of the ``Logger`` class.
-This argument specifies how to handle the stream.
+A common habit while prototyping a new feature is to print message into the
+command line executable. Instead of using the common ``Print()`` method, it is
+advised to use a ``StreamHandler`` and redirect its content. Indeed that will
+allow to filter messages based on their level and apply properly the formatter.
+To do so, a boolean argument can be added in the initializer of the ``Logger``
+class. This argument specifies how to handle the stream.
Enable/Disable handlers
~~~~~~~~~~~~~~~~~~~~~~~
-Sometimes the user might want to disable specific handlers such as a
-file handler where log messages are written. If so, the existing
-handler must be properly closed and removed. Otherwise the file access
-might be denied later when you try to write new log content.
+Sometimes the user might want to disable specific handlers such as a file
+handler where log messages are written. If so, the existing handler must be
+properly closed and removed. Otherwise the file access might be denied later
+when you try to write new log content.
Here's one approach to closing log handlers.
@@ -70,12 +71,13 @@ Here's one approach to closing log handlers.
App Filter
~~~~~~~~~~
-A filter shows all its value when the content of a message depends on some conditions.
-It injects contextual information in the core of the message.
-This can be useful to harmonize the message rendering when the application output is not consistent
-and vary upon the data processed.
-It requires the creation of class based on the logging.Filter and the implementation of
-the ``filter`` method. This method will contain all the modified content send to the stream.
+A filter shows all its value when the content of a message depends on some
+conditions. It injects contextual information in the core of the message.
+This can be useful to harmonize the message rendering when the application
+output is not consistent and vary upon the data processed.
+It requires the creation of class based on the logging.Filter and the
+implementation of the ``filter`` method. This method will contain all the
+modified content send to the stream.
.. code:: python
@@ -113,12 +115,12 @@ the ``filter`` method. This method will contain all the modified content send to
String format
~~~~~~~~~~~~~
-Even if the current practice recommends using the f-string to format
-most strings, when it comes to logging, the former %-formatting is
-preferable. This way the string format is not evaluated at
-runtime. It is deferred and evaluated only when the message is
-emitted. If there is any formatting or evaluation error, these will be
-reported as logging errors and will not halt code execution.
+Even if the current practice recommends using the f-string to format most
+strings, when it comes to logging, the former %-formatting is preferable. This
+way the string format is not evaluated at runtime. It is deferred and evaluated
+only when the message is emitted. If there is any formatting or evaluation
+error, these will be reported as logging errors and will not halt code
+execution.
.. code:: python
@@ -127,18 +129,16 @@ reported as logging errors and will not halt code execution.
Application or Service Logging
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The following guidelines describe "Application" or "Service" logging
-module for a PyAnsys library, where a PyAnsys library is used to
-extend or expose features from an Ansys application, product, or
-service that may be local or remote.
-
-This section describes two main loggers for a PyAnsys library that
-exposes or extends a service based application, the *Global logger*
-and the *Instance logger*. These loggers are customized classes that wrap
-:class:`logging.Logger` from :mod:`logging` module and add specific
-features to it. :ref:`logging_in_pymapdl_figure` outlines the logging
-approach used by PyMAPDL and the scopes of the global and local
-loggers.
+The following guidelines describe "Application" or "Service" logging module for
+a PyAnsys library, where a PyAnsys library is used to extend or expose features
+from an Ansys application, product, or service that may be local or remote.
+
+This section describes two main loggers for a PyAnsys library that exposes or
+extends a service based application, the *Global logger* and the *Instance
+logger*. These loggers are customized classes that wrap :class:`logging.Logger`
+from :mod:`logging` module and add specific features to it.
+:ref:`logging_in_pymapdl_figure` outlines the logging approach used by PyMAPDL
+and the scopes of the global and local loggers.
.. _logging_in_pymapdl_figure:
@@ -167,14 +167,13 @@ Following are some unit tests demonstatring how to use the code implemented abov
Example Global logger
~~~~~~~~~~~~~~~~~~~~~
-There is a global logger named ``py*_global`` which is created when
-importing ``ansys.product.service``
-(``ansys.product.service.__init__``). This logger is recommended for
-most scenarios, especially when complex modules or classes are not
-involved, since it does not track instances, rather can be used
-globally. If you intend to log the initialization of a library or
-module, you should use this logger. To use this global logger, you
-must import it at the top of your script or module:
+There is a global logger named ``py*_global`` which is created when importing
+``ansys.product.service`` (``ansys.product.service.__init__``). This logger is
+recommended for most scenarios, especially when complex modules or classes are
+not involved, since it does not track instances, rather can be used globally.
+If you intend to log the initialization of a library or module, you should use
+this logger. To use this global logger, you must import it at the top of your
+script or module:
.. code:: python
@@ -216,13 +215,12 @@ you can add a file handler using:
file_path = os.path.join(os.getcwd(), 'pylibrary.log')
LOG.log_to_file(file_path)
-This enables logging to that file in addition of the standard output.
-If you wish to change the characteristics of this global logger from
-the beginning of the execution, you must edit the file ``__init__`` in
-the directory of your library.
+This enables logging to that file in addition of the standard output. If you
+wish to change the characteristics of this global logger from the beginning of
+the execution, you must edit the file ``__init__`` in the directory of your
+library.
-To log using this logger, simply call the desired method as a normal
-logger.
+To log using this logger, simply call the desired method as a normal logger.
.. code:: python
@@ -237,13 +235,13 @@ logger.
Instance logger
~~~~~~~~~~~~~~~
-Every time that the class ``_MapdlCore`` is instantiated, a logger is
-created. This logger is recommended when using the ``pool`` library
-or when using multiple instances of ``Mapdl``. The main feature of
-this logger is that it tracks each instance and it includes its name
-when logging. The name of the instances are unique. For example in
-case of using the ``gRPC`` ``Mapdl`` version, its name includes the IP
-and port of the correspondent instance, making unique its logger.
+Every time that the class ``_MapdlCore`` is instantiated, a logger is created.
+This logger is recommended when using the ``pool`` library or when using
+multiple instances of ``Mapdl``. The main feature of this logger is that it
+tracks each instance and it includes its name when logging. The name of the
+instances are unique. For example in case of using the ``gRPC`` ``Mapdl``
+version, its name includes the IP and port of the correspondent instance, making
+unique its logger.
The instance loggers can be accessed in two places:
@@ -252,11 +250,11 @@ The instance loggers can be accessed in two places:
* ``LOG._instances``. This field is a ``dict`` where the key is the
name of the created logger.
-These instance loggers inherit from the ``pymapdl_global`` output
-handlers and logging level unless otherwise specified. The way this
-logger works is very similar to the global logger. You can add a file
-handler if you wish using the method ``log_to_file`` or change the log
-level using :meth:`logging.Logger.setLevel`.
+These instance loggers inherit from the ``pymapdl_global`` output handlers and
+logging level unless otherwise specified. The way this logger works is very
+similar to the global logger. You can add a file handler if you wish using the
+method ``log_to_file`` or change the log level using
+:meth:`logging.Logger.setLevel`.
You can use this logger like this:
@@ -274,17 +272,22 @@ You can use this logger like this:
Wrapping Other Loggers
~~~~~~~~~~~~~~~~~~~~~~
-A product, due to its architecture can be made of several loggers.
-The ``logging`` library features allows to work with a finite number of loggers.
-The factory function logging.getLogger() helps to access each logger by its name.
-In addition of this naming-mappings, a hierachy can be established to structure the loggers
-parenting and their connection.
-
-
-For instance, if an ANSYS product is using a pre-exsiting custom logger encapsulated inside the product itself, the will benefit from exposing it through the standard python tools.
-It is recommended to use the standard library as much as possible. It will facilitate every contribution -both external and internal- to the by exposing common tools that are widely spread.
-Each developer will be able to operate quickly and autonomously.
-The project will take advantage of the entire set of features exposed in the standard logger and all the upcoming improvements.
+A product, due to its architecture can be made of several loggers. The
+``logging`` library features allows to work with a finite number of loggers. The
+factory function logging.getLogger() helps to access each logger by its name. In
+addition of this naming-mappings, a hierachy can be established to structure the
+loggers parenting and their connection.
+
+
+For instance, if an ANSYS product is using a pre-exsiting custom logger
+encapsulated inside the product itself, the will benefit from
+exposing it through the standard python tools. It is recommended to use the
+standard library as much as possible. It will facilitate every contribution
+-both external and internal- to the by exposing common tools that
+are widely spread. Each developer will be able to operate quickly and
+autonomously.
+The project will take advantage of the entire set of features exposed in the
+standard logger and all the upcoming improvements.
Create a custom log handler to catch each product message and redirect them on another logger:
==============================================================================================
@@ -298,9 +301,12 @@ AEDT product has its own internal logger called the message manager made of 3 ma
* *Project*: related to the project
* *Design*: related to the design (most specific destination of each 3 loggers.)
-The message manager is not using the standard python logging module and this might be a problem later when exporting messages and data from each ANSYS product to a common tool.
-In most of the cases, it is easier to work with the standard python module to extract data.
-In order to overcome this limitation, the existing message manager is wrapped into a logger based on the standard python `logging `__ module.
+The message manager is not using the standard python logging module and this
+might be a problem later when exporting messages and data from each ANSYS
+product to a common tool. In most of the cases, it is easier to work with the
+standard python module to extract data.
+In order to overcome this limitation, the existing message manager is wrapped
+into a logger based on the standard python :mod:`logging` module.
.. figure:: images/log_flow.png
@@ -311,8 +317,10 @@ In order to overcome this limitation, the existing message manager is wrapped in
**Figure 1: Loggers message passing flow.**
-This wrapper implementation boils down to a custom handler. It is based on a class inherited from logging.Handler.
-The initializer of this class will require the message manager to be passed as an argument in order to link the standard logging service with the ANSYS internal message manager.
+This wrapper implementation boils down to a custom handler. It is based on a
+class inherited from logging.Handler. The initializer of this class will require
+the message manager to be passed as an argument in order to link the standard
+logging service with the ANSYS internal message manager.
.. code:: python
@@ -330,9 +338,17 @@ The initializer of this class will require the message manager to be passed as a
The purpose of this class is to send log messages in AEDT logging stream.
-One of the mandatory actions is to overwrite the ``emit`` function. This method operates as a proxy. It will dispatch all the log message toward the message manager.
-Based on the record level, the message is sent to the appropriate log level (debug, info, error...) into the message manager to fit the level provided by the ANSYS product.
-As a reminder the record is an object containing all kind of information related to the event logged.
-
-This custom handler is used into the new logger instance (the one based on the standard library).
-A good practice before to add a handler on any logger is to verify if any appropriate handler is already available in order to avoid any conflict, message duplication...
+One of the mandatory actions is to overwrite the ``emit`` function. This method
+operates as a proxy. It will dispatch all the log message toward the message
+manager.
+Based on the record level, the message is sent to the appropriate log level
+(debug, info, error...) into the message manager to fit the level provided by
+the ANSYS product.
+As a reminder the record is an object containing all kind of information related
+to the event logged.
+
+This custom handler is used into the new logger instance (the one based on the
+standard library).
+A good practice before to add a handler on any logger is to verify if any
+appropriate handler is already available in order to avoid any conflict, message
+duplication...