deceze
deceze

Reputation: 522451

How to log/debug a Crossbar guest worker?

How can I capture output/logs from a guest worker and/or debug it? The worker is a regular Python3 Autobahn WAMP component. Whatever I print or raise or write to stderr is nowhere to be found; or I don't know where to look. Only if the guest terminates with an error is anything output to the Crossbar log. Here's the configuration:

workers:
  - type:       guest
    executable: python3
    arguments:  ['../foo.py']
    options:
      stdout: log
      stderr: log

The stdout and stderr options seem to make no difference whatsoever.

Versions:

Upvotes: 1

Views: 2001

Answers (3)

JulienMN
JulienMN

Reputation: 86

I had a similar issue of crossbar not outputting anything after the initial startup. Even though there are console.log() in the code. In my case it is with the node.js crossbar router.

The solution was to add "--loglevel=debug" to the start command

crossbar start --loglevel=debug

Then I started seeing output when console.log() where executed.

Upvotes: 1

meejah
meejah

Reputation: 316

By default, Python stdout/stderr is buffered so crossbar won't see the logs from the guest when you might think.

You can either set the environment variable PYTHONUNBUFFERED=1 or pass the -u option to your interpreter.

Upvotes: 2

Eddie
Eddie

Reputation: 1063

crossbar check validates stdout: log and stderr: log but Im not sure why it doesn't log the errors.

I normally do it like below but your config looks more clean and handy.

Setup

Follow this (Debugging Crossbar.io app in IntelliJ). Do similar thing for the IDE you use, however, I recommend to use PyPy for crossbar router instead of CPython.

Logging

Follow this (Logging WAMP worker Trace Back Error). You just gotta enable the Trace Back Error logging feature. You can import traceback and use try except or just use create a simple __init__ function like below:

class MyComponent(ApplicationSession):
   def __init__(self, config = None):
      ApplicationSession.__init__(self, config)
      self.traceback_app = True

Below is a full working example:

Error log

enter image description here

.crossbar/config.yaml

controller: {}
workers:
- realms:
  - name: realm1
    roles:
    - name: anonymous
      permissions:
      - {call: true, publish: true, register: true, subscribe: true, uri: '*'}
  transports:
  - endpoint: {port: 8080, type: tcp}
    paths:
      /: {directory: .., type: static}
      ws: {type: websocket}
    type: web
  type: router
- arguments: [backend.py]
  executable: ../../../.pyenv/versions/autobahn/bin/python3
  options:
    watch:
      action: restart
      directories: [..]
    workdir: ..
  type: guest

backend.py

from autobahn.asyncio.wamp import ApplicationSession
from autobahn import wamp

from asyncio import coroutine
import logging


class MyComponent(ApplicationSession):
    def __init__(self, config = None):
        ApplicationSession.__init__(self, config)
        self.traceback_app = True

    @wamp.register("com.myapp.add2")
    def add2(self, x, y):
        if type(y) is str:
            error = ' Sorry! Python can not add int with something else :('
            logging.critical(error)
            return error

        return x + y

    @coroutine
    def onJoin(self, details):
        res = yield from self.register(self)
        print("{} procedures registered.".format(len(res)))

if __name__ == '__main__':
    from autobahn.asyncio.wamp import ApplicationRunner

    runner = ApplicationRunner(url="ws://localhost:8080/ws", realm="realm1")
    runner.run(MyComponent)

frontend.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
<script>AUTOBAHN_DEBUG = false;</script>
<script src="http://autobahn.s3.amazonaws.com/autobahnjs/latest/autobahn.min.jgz"></script>

<script>
    var connection = new autobahn.Connection({
        url: "ws://localhost:8080/ws",
        realm: "realm1"
    });

    connection.onopen = function (session, details) {
        // Should work
        session.call("com.myapp.add2", [1, 2]).then(session.log);

        // Expected to log an error
        session.call("com.myapp.add2", [2, "three"]).then(session.log);

        // Expected to log the trace back error
        session.call("com.myapp.add2", ["one", 5]).then(session.log);
    };

    connection.onclose = function (reason, details) {
        console.log("Connection lost: " + reason);
    };

    connection.open();
</script>
</body>
</html>

Upvotes: 1

Related Questions