-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
stack_info Doesn't include stack info when sending to Seq Server #42
Comments
I was able to add an exception property to the log body using a custom
Seems like this could be pretty easily integrated with the main Reasoning:
|
Thanks for the detailed report! I like this idea - will give it a try this weekend 🙂 |
Thanks for your patience, and sorry for the delay! Published v0.3.23 🙂 |
I'm seeing this feature add the stack information twice to stdout in all of the following cases:
The last one is especially curious. Is this expected? or is there possibly something wrong with my implementation? |
Hmm, no shouldn’t be! Will have a look in my lunch break and see what I can see :) |
I tested it with this code and got the same results; double stack traces.
|
Do the stack traces sent to Seq also get doubled up? |
Found it! If it helps, here's the call stack that I was seeing when the code hit the default formatter.
|
Nice catch! I'll fix that up shortly :) |
Hmm, so it sounds if Might be a little tricky to work out at runtime (does |
So the I think it might be cleaner if (like the second code block of my second comment on Jan 9th) you revised the |
Ok, yes, I think that makes sense to me (sorry, it's been a while since I looked at this code and I'm waiting for the coffee to kick in!). Effectively, we're just talking about removing the code that caches the exception info in |
Yes, so I think what you have in My modification/override to/of |
Ah, ok - you mean we get rid of: if sinfo and not record.exc_text:
setattr(record, 'exc_text', sinfo) ? |
Gotcha! All good, doing it now :) |
Correct. That |
Published v0.3.24! 🙂 |
stdout/lastResort looks much better with that change! 👍 I'll test it out with a Seq server and some more custom things tomorrow. |
Thanks! |
Looks good! Thanks for pushing that update! :) |
for some reason my logging instance is adding a bunch of
It's also not adding the stack information to the logs. :/ |
So far it doesn't seem to be the It's also logging everything 3 times. 😮 |
Is this what’s going to Seq or what’s being logged elsewhere? |
Yes, that Json is what I get from the seq server when I download the raw log item. |
Hmm, I wonder if this is a regression with the recent changes or something environmental (e.g. Python version)… |
I added some |
oh wow. definitely my implementation. ... I had the handler and logger set up indented one-too-many times and it was included in a However, it's serializing my extra properties and escaping the double-quotes still. So the record still looks like this:
for some reason it's escaping each extra property string rather than taking them as single strings. Looks like it's getting processed the same way as the stack info. |
looks like it's this line in UPDATE: Is that UPDATE 2: I'm testing this log without any actual exceptions going on in my code, so that's sort of not surprising. If I did, it seems like that would be included. I see both the Could you add a check near the end of |
This might just be another implementation thing...
Seems like I should either include |
@Vacant0mens - whatever the issue is, it seems to be affecting other users too; I’m going to roll back that last change (the one that fixed the console logging issue) in the published package (just for now) while we figure out what’s going on. |
Okay. Thanks for rolling back. Sorry for the issues.
Feel free to modify/update this code as needed to make it work better than my crude tests.
You'd need to be careful not to use |
Nice work! 🙂 |
@Vacant0mens - I think this is probably sufficient to fix the problem (regardless of any other behavioural changes): def best_effort_json_encode(arg):
# No encoding necessary for strings.
if isinstance(arg, str):
return arg
try:
return json.dumps(arg)
except TypeError:
try:
return str(arg)
except TypeError:
try:
return repr(arg)
except TypeError:
return '<type %s>' % (type(arg), )
except ReferenceError:
return '<gone weak reference>' What do you reckon? |
Published v0.3.26. It seems to work as far as I've been able to test it, but I don't have access to my old Seq instance so have had to rely on somewhat more theoretical testing than usual 🙂 |
yeah, as long as the end-goal of this method is to always return a string, this would be fine. 👍 |
Has any more testing been done on that version? If not, I can test it a bit. Otherwise, can this issue be closed? |
I'd appreciate it if you could try it out and see if it works for your use-case; if it works for you I'd be happy to close this issue 🙂 Thanks! |
yep. I'm able to log stack trace info with the |
looks like the default From def format(self, record):
"""
Format the specified record as text.
The record's attribute dictionary is used as the operand to a
string formatting operation which yields the returned string.
Before formatting the dictionary, a couple of preparatory steps
are carried out. The message attribute of the record is computed
using LogRecord.getMessage(). If the formatting string uses the
time (as determined by a call to usesTime(), formatTime() is
called to format the event time. If there is exception information,
it is formatted using formatException() and appended to the message.
"""
record.message = record.getMessage()
if self.usesTime():
record.asctime = self.formatTime(record, self.datefmt)
s = self.formatMessage(record)
if record.exc_info:
# Cache the traceback text to avoid converting it multiple times
# (it's constant anyway)
if not record.exc_text:
record.exc_text = self.formatException(record.exc_info)
if record.exc_text:
if s[-1:] != "\n":
s = s + "\n"
s = s + record.exc_text
if record.stack_info:
if s[-1:] != "\n":
s = s + "\n"
s = s + self.formatStack(record.stack_info)
return s I added a couple lines to the beginning of def emit(self, record):
if record.exc_text and not record.exc_info:
record.exc_text = ''
msg = self.format(record)
print(msg)
if hasattr(record, 'kwargs'):
print("\tLog entry properties: {}".format(repr(record.kwargs))) This cleared up the double-stack issue in the console logs, but this might not be the best place for it. |
Good catch! Happy to take a PR for that or can make the change myself if you prefer :) |
Ah, I think I found why it was logging double stacks to the console. A change from earlier in if sinfo and not record.exc_text:
setattr(record, 'exc_text', sinfo) I'll test with latest master and see if there's anything else. |
Yep. That looks much better. I'll make a PR to clean out those two lines. 👍 |
…ing.py initial attempt at resolving Issue tintoy#42 ( `stack_info=True` not adding stack info to the logs going to the Seq server) was causing the stack to be printed twice into the console logs
Description
adding
stack_info=True
doesn't add a stack trace or anything to the REST request body (using StructuredLogger), but it does in the ConsoleStructuredLogger (which, as we know, only writes to console).What I Did
Added a custom class over
seqlog.StructuredLogger
and created a custommakeRecord
function. (this worked, but didn't add it to the Exception field.)I attempted to create a custom
StructuredLogHandler
class with a custom_build_event_data
function that calledevent_data = super()._build_event_data()
and then added stack information to theException
field (usingseqlog.StructuredLogger.findCaller()
), but the Seq server responded with a 500:Is there documentation on the REST Api that is more clear about what fields are available for use cases like this?
Pages for Using the REST Api and Server Api Endpoints don't include what body parameters are available nor what is required for each endpoint.
If they did, I would add a commit myself for this issue.
The text was updated successfully, but these errors were encountered: