2018-05-23 05:31:34 +08:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
import asyncio
|
|
|
|
import struct
|
|
|
|
import logging
|
|
|
|
import re
|
|
|
|
|
|
|
|
from artiq.tools import *
|
|
|
|
from artiq.protocols.pc_rpc import Server
|
|
|
|
from artiq.protocols.logging import log_with_name
|
|
|
|
from artiq.coredevice.comm_mgmt import Request, Reply
|
|
|
|
|
|
|
|
|
|
|
|
def get_argparser():
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
description="ARTIQ controller for core device logs")
|
|
|
|
simple_network_args(parser, 1068)
|
2019-04-19 23:42:37 +08:00
|
|
|
parser.add_argument("--simulation", action="store_true",
|
|
|
|
help="Simulation - does not connect to device")
|
2018-09-15 10:43:50 +08:00
|
|
|
parser.add_argument("core_addr", metavar="CORE_ADDR",
|
2018-05-23 05:31:34 +08:00
|
|
|
help="hostname or IP address of the core device")
|
|
|
|
return parser
|
|
|
|
|
|
|
|
|
|
|
|
class PingTarget:
|
|
|
|
def ping(self):
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
2019-04-19 23:42:37 +08:00
|
|
|
async def get_logs_sim(host):
|
|
|
|
while True:
|
|
|
|
await asyncio.sleep(2)
|
|
|
|
log_with_name("firmware.simulation", logging.INFO, "hello " + host)
|
|
|
|
|
|
|
|
|
2018-05-23 05:31:34 +08:00
|
|
|
async def get_logs(host):
|
|
|
|
reader, writer = await asyncio.open_connection(host, 1380)
|
|
|
|
writer.write(b"ARTIQ management\n")
|
|
|
|
writer.write(struct.pack("B", Request.PullLog.value))
|
|
|
|
await writer.drain()
|
|
|
|
|
|
|
|
while True:
|
|
|
|
length, = struct.unpack(">l", await reader.readexactly(4))
|
|
|
|
log = await reader.readexactly(length)
|
|
|
|
|
|
|
|
for line in log.decode("utf-8").splitlines():
|
|
|
|
m = re.match(r"^\[.+?\] (TRACE|DEBUG| INFO| WARN|ERROR)\((.+?)\): (.+)$", line)
|
|
|
|
levelname = m.group(1)
|
|
|
|
if levelname == 'TRACE':
|
|
|
|
level = logging.TRACE
|
|
|
|
elif levelname == 'DEBUG':
|
|
|
|
level = logging.DEBUG
|
|
|
|
elif levelname == ' INFO':
|
|
|
|
level = logging.INFO
|
|
|
|
elif levelname == ' WARN':
|
|
|
|
level = logging.WARN
|
|
|
|
elif levelname == 'ERROR':
|
|
|
|
level = logging.ERROR
|
|
|
|
name = 'firmware.' + m.group(2).replace('::', '.')
|
|
|
|
text = m.group(3)
|
|
|
|
log_with_name(name, level, text)
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
args = get_argparser().parse_args()
|
|
|
|
|
|
|
|
loop = asyncio.get_event_loop()
|
|
|
|
try:
|
2019-04-19 23:42:37 +08:00
|
|
|
get_logs_task = asyncio.ensure_future(
|
|
|
|
get_logs_sim(args.core_addr) if args.simulation else get_logs(args.core_addr))
|
2018-05-23 05:31:34 +08:00
|
|
|
try:
|
|
|
|
server = Server({"corelog": PingTarget()}, None, True)
|
|
|
|
loop.run_until_complete(server.start(bind_address_from_args(args), args.port))
|
|
|
|
try:
|
|
|
|
multiline_log_config(logging.TRACE)
|
|
|
|
loop.run_until_complete(server.wait_terminate())
|
|
|
|
finally:
|
|
|
|
loop.run_until_complete(server.stop())
|
|
|
|
finally:
|
|
|
|
get_logs_task.cancel()
|
|
|
|
try:
|
|
|
|
loop.run_until_complete(get_logs_task)
|
|
|
|
except asyncio.CancelledError:
|
|
|
|
pass
|
|
|
|
finally:
|
|
|
|
loop.close()
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|