Skip to content
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

get log file after session run #267

Closed
Wouter1 opened this issue Feb 10, 2021 · 12 comments
Closed

get log file after session run #267

Wouter1 opened this issue Feb 10, 2021 · 12 comments
Assignees
Labels
question Further information is requested

Comments

@Wouter1
Copy link

Wouter1 commented Feb 10, 2021

What is your question?
How do I get the filename of the log file after a session run.
Because after the run I need to analyze the log file and extract statistics.

At this moment I try to use builder.loggers[0]._GridWorldLogger__file_name

This is very bad because this should be an anonymous internal variable.
Also I need to hard code the knowledge that it's in world_1.

@Wouter1 Wouter1 added the question Further information is requested label Feb 10, 2021
@Wouter1
Copy link
Author

Wouter1 commented Feb 10, 2021

BTW I tried the _GridWorldLogger__file_name but it does not even work.
I have no workaround for this so I'm stuck on this

@jwaa
Copy link
Member

jwaa commented Feb 10, 2021

@Wouter1 I will take a look at it in a moment. Is this for a custom logger class or one of those of MATRX?

@Wouter1
Copy link
Author

Wouter1 commented Feb 10, 2021

@jwaa This is for running after main call completed.
So when gridworld.run() returns, I want to read the log file.
At that point I have a handle to the builder and possibly to the gridworld,
so also to builder.loggers[]. But I can't get the actual log file

@Wouter1
Copy link
Author

Wouter1 commented Feb 10, 2021

@jwaa I'm using my own logger class for this. But it looks irrelevant, I'm extending the GridWorldLogger and I leave all file handling to the GridWorldLogger.

@jwaa
Copy link
Member

jwaa commented Feb 10, 2021

Access with GridWorldLogger._GridWorldLogger__file_name would be a work around (although an ugly one as you said). The problem why this does not work is likely because builder does not store the instances, but the classes. That is why you pass the class to the WorldBuilder.add_logger() method. The instance is made for every newly create world to ensure that every logger is unique. So with WorldBuilder.loggers you get a list of the form [(TheLoggerClass, {constructor_argument_name: value, ...}), ...].

This will not contain anything that gets you the file name.

A solution is, making use of your custom class, is to make the file name accessible through a Python Property decorator:

class YourLogger(GridWorldLogger):
    ...
    @property
    def file_name():
        return self.__file_name

This makes it publicly acessible but not changeable: fn = your_logger.file_name.

That is the easy part, but we still need a workaround to get access to the logger instance from the GridWorld instance. Sadly, these do not have a publicly available list of loggers (I made a feature request for it; #268).

So the workaround is:

builder = create_builder()
world = builder.get_world()
world.run()
loggers = world._GridWorld__loggers
fn_first_logger = loggers[0].file_name

This assumes that the previous code segment is present in all of your custom loggers and that the world only contains your custom loggers. If this is not the case, we need to figure out a different solution.

@Wouter1
Copy link
Author

Wouter1 commented Feb 10, 2021

@jwaa ah, sorry I somehow did not get notified about your comment here. Thanks, I'll look into this workaround once you have a fix for #288.

@jwaa
Copy link
Member

jwaa commented Feb 10, 2021

@Wouter1; To clarify, the workaround I provided can be done right now. I cannot guarantee that issue #268 will be implemented quick enough for you. So it might be an idea to implement the workaround now instead of waiting for #268.

I assume here that you refer to #268, since #288 does not exist (yet).

@Wouter1
Copy link
Author

Wouter1 commented Feb 15, 2021

@jwaa Thanks!
The workaroiund works with one amendment

fn_first_logger = loggers[0].file_name

needs to be (again hacking around private variable protection)

fn_first_logger = loggers[0]._GridWorldLogger__file_name

@jwaa
Copy link
Member

jwaa commented Feb 17, 2021

Yes, this is needed if you did not added the code segment I added; since you have your custom logger class, you can easily make file_name a publicly accessible attribute by making it a property with only a getter (and not setter). I refer to this code segment in my answer:

class YourLogger(GridWorldLogger):
    ...
    @property
    def file_name():
        return self.__file_name

@Wouter1
Copy link
Author

Wouter1 commented Feb 17, 2021

@jwaa Ah yes, but that would make the code dependent on the specific YourLogger. I prefer the more generally working code. It would be best though if file_name function were added to GridWorldLogger itself.

@jwaa
Copy link
Member

jwaa commented Feb 17, 2021

@jwaa Ah yes, but that would make the code dependent on the specific YourLogger. I prefer the more generally working code. It would be best though if file_name function were added to GridWorldLogger itself.

I absolutely agree on this, I however wanted to suggest a workaround that works and does not look 'hacky'. I didn't found the time back then to make a feature request for it and forgot about it then. I now made one; #270

@thaije
Copy link
Collaborator

thaije commented May 27, 2022

#270 and #268 have been closed and should fix this issue.

@thaije thaije closed this as completed May 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants