schubergphilis / towerlib

A python library to interface with ansible tower's (awx) api.
MIT License
43 stars 39 forks source link

Job Launch Failures not displaying reason #91

Closed jitterjuice closed 3 years ago

jitterjuice commented 3 years ago

Hello,

First of all - great library! been using it internally and it has made my life a whole lot easier :)

I have noticed that when a job template is launched (whereby a survey or variable is missing, credential cant be found etc), it returns None as expected (based on the entity code), however the logger when resp.ok is not true is not displaying the actual output.

I have attempted to use the default logging framework, however that did not yield any output. My current project is using loguru to handle logging, with my test cases failing as expected.. however without a displayable cause.

Is it expected that the log message (https://github.com/schubergphilis/towerlib/blob/e4ae19f7b88d7049e1f23f279040461fa464c6e9/towerlib/entities/job.py#L1365) should be displayed? (i.e., pk credential not found, missing survey vars)

If not.. how can this be caught to surface the reason of failure?

Cheers, Jeremy

jitterjuice commented 3 years ago

My immediate local solution here was to return response instead of None, such that the response.text can be surfaced as an error and handled as necessary. Open to suggestions :)

if not response.ok:
            self._logger.error('Error launching job %s, response was :%s', self.name, response.text)
            return response
costastf commented 3 years ago

Hi @jitterjuice , i am very happy to hear that the library is useful to you, very nice of you to share :) Now as for the problem you are mentioning, i am a bit confused as to what the problem is exactly. The code that launches a job should either return a Job object on success or None on failure. I hope that this makes sense since when you do not launch something you should not expect something. Now, the way the code is written if you do not have a valid response (response.ok is not True) then the code logs with an error level the text provided along with the response which should have the cause of the issue thus helping you to identify what went wrong. Returning the response object would not solve anything since the only piece of information as to the cause would be in that text that is logged apart from braking the interface of the Job launch returning something that is unexpected.

You mention that you do not see the logging which leads me to ask you to show me how you are setting up your logging to see if the problem lies there. I hope this makes sense and that I understand the problem properly.

jitterjuice commented 3 years ago

Hi @costastf,

I understand the job is not expected to launch, and it makes sense returning None. The logic itself makes sense, I guess my root problem comes down to implementing a separate logger (loguru here instead of pythons logging), which is causing the error message to not be displayed as you've called out.

Ill keep investigating to see if i can sink pythons logging output to loguru, but any suggestions would be appreciated :)

EDIT: The following snippet will capture any logging messages and forward to loguru.

import logging
from loguru import logger

class InterceptHandler(logging.Handler):
    def emit(self, record):
        # Get corresponding Loguru level if it exists
        try:
            level = logger.level(record.levelname).name
        except ValueError:
            level = record.levelno

        # Find caller from where originated the logged message
        frame, depth = logging.currentframe(), 2
        while frame.f_code.co_filename == logging.__file__:
            frame = frame.f_back
            depth += 1

        logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())

logging.basicConfig(handlers=[InterceptHandler()], level=0)

By applying the above snippet to the loguru config, the appropriate messages are passed.

Thankyou for the reply @costastf

costastf commented 3 years ago

I was just about to paste that here since i looked for this (had not seen the edit ) :) I am happy that your problem is solved, have a great day!