Skip to content

Commit

Permalink
Feature/more logging (#191)
Browse files Browse the repository at this point in the history
* document new feature

* test for maxLogLength

* add maximum log length parameter

* remove unused variable

* consistent implementation
  • Loading branch information
Fedor Baart authored Apr 23, 2022
1 parent ec90612 commit 1806b28
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ There are two types of configuration: Defaults applying to every environment and
| agentTimeout | Maximum runtime (seconds) to initialize an agent. |
| actTimeout | Maximum runtime (seconds) to obtain an action from an agent. |
| runTimeout | Maximum runtime (seconds) of an episode (not necessarily DONE). |
| maxLogLength | Maximum log length (number of characters, `None` -> no limit) |

```python
env = make("connectx", configuration={
Expand Down
17 changes: 12 additions & 5 deletions kaggle_environments/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def get_last_callable(raw, fallback=None, path=None):
# append exec_dir so that way python agents can import other files
exec_dir = os.path.dirname(path)
sys.path.append(exec_dir)

exec(code_object, env)
sys.path.pop()
sys.stdout = orig_out
Expand Down Expand Up @@ -160,10 +160,17 @@ def act(self, observation):
except Exception as e:
traceback.print_exc(file=err_buffer)
action = e
# Allow up to 1k log characters per step which is ~1MB per 600 step episode
max_log_length = 1024
out = out_buffer.getvalue()[0:max_log_length]
err = err_buffer.getvalue()[0:max_log_length]

out = out_buffer.getvalue()
err = err_buffer.getvalue()
# Get the maximum log length
# Allow up to 1k (default) log characters per step which is ~1MB per 600 step episode
max_log_length = self.configuration.get('maxLogLength', 1024)

# truncate if max_log_length is set to None, do not truncate
if max_log_length is not None:
out = out[0:max_log_length]
err = err[0:max_log_length]

duration = perf_counter() - start
log = {
Expand Down
14 changes: 10 additions & 4 deletions kaggle_environments/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,14 +600,20 @@ def __run_interpreter(self, state, logs):
# Reraise e to ensure that the program exits
raise e
finally:
# Allow up to 1k log characters per step which is ~1MB per 600 step episode
max_log_length = 1024
out = out_buffer.getvalue()
err = err_buffer.getvalue()

# strip if needed
# Allow up to 1k (default) log characters per step which is ~1MB per 600 step episode
max_log_length = self.configuration.get("maxLogLength", 1024)
if max_log_length is not None:
out = out[0:max_log_length]
err = err[0:max_log_length]

if out or err:
logs.append({
"stdout": out[0:max_log_length],
"stderr": err[0:max_log_length]
"stdout": out,
"stderr": err
})
finally:
if out:
Expand Down
18 changes: 18 additions & 0 deletions kaggle_environments/envs/connectx/test_connectx.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,21 @@ def test_can_evaluate():
rewards = evaluate("connectx", ["random", "random"], num_episodes=2)
assert (rewards[0][0] + rewards[0][1] ==
0) and rewards[1][0] + rewards[1][1] == 0


def test_max_log_length():
def custom1():
# Write 20X to stdtout, we should strip to 10
print('X' * 20)
return 1

def custom2():
return 2
before_each(
# here we strip log to length 10
configuration={"rows": 4, "columns": 5, "inarow": 3, "maxLogLength": 10},
)
env.run([custom1, custom2])
last_log = env.logs[-1][0]['stdout']
assert env.configuration.maxLogLength == 10, "max log length should be set to 10"
assert len(last_log.strip()) == 10, "max log length should be 10 (+ newline, which we stripped)"

0 comments on commit 1806b28

Please sign in to comment.