| #!/usr/bin/env python |
| # |
| # Copyright 2018 Google Inc. All Rights Reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """Example script for getting the Net log.""" |
| |
| from __future__ import print_function |
| |
| import argparse |
| import pprint |
| import select |
| import socket |
| import sys |
| import time |
| import threading |
| |
| class NetLog: |
| """ |
| Uses a non-blocking socket to establish a connection with a |
| NetLog and then will allow the log to be fetched. |
| """ |
| def __init__(self, host, port): |
| self.host = host |
| self.port = port |
| self.server_socket = None |
| |
| def FetchLog(self): |
| if not self.server_socket: |
| self.server_socket = self._TryCreateSocketConnection() |
| if not self.server_socket: |
| return None |
| try: |
| log = self._TryRead() |
| if log is None: |
| self.server_socket = None |
| else: |
| return log |
| except socket.error as (err_no, err_str): |
| print(__file__ + ": Socket error while reading log:" \ |
| + str(err_no) + " - " + str(err_str)) |
| self.server_socket = None |
| return None |
| |
| # Private members |
| def _TryRead(self): |
| try: |
| ready_list, _, _ = select.select([self.server_socket], [], []) |
| if not ready_list: |
| return '' |
| result = self.server_socket.recv(1024) |
| # An empty string is a flag that the connection has closed. |
| if len(result) == 0: |
| return None |
| return result |
| except socket.error as (err_no, err_str): |
| if err_no == 10035: # Data not ready yet. |
| return '' |
| else: |
| raise |
| |
| def _TryCreateSocketConnection(self): |
| try: |
| print("Waiting for connection to " + str(self.host) + ':' + str(self.port)) |
| |
| server_socket = socket.create_connection((self.host, self.port), timeout = 1) |
| server_socket.setblocking(0) |
| return server_socket |
| except socket.timeout as err: |
| return None |
| except socket.error as err: |
| print("Error while trying to create socket: " + str(err)) |
| return None |
| |
| |
| class NetLogThread(threading.Thread): |
| """Threaded version of NetLog""" |
| def __init__(self, host, port): |
| super(NetLogThread, self).__init__() |
| self.web_log = NetLog(host, port) |
| self.alive = True |
| self.log_mutex = threading.Lock() |
| self.log = [] |
| self.start() |
| |
| def join(self): |
| self.alive = False |
| return super(NetLogThread, self).join() |
| |
| def GetLog(self): |
| with self.log_mutex: |
| log_copy = self.log |
| self.log = [] |
| return ''.join(log_copy) |
| |
| def run(self): |
| while self.alive: |
| new_log = self.web_log.FetchLog() |
| if new_log: |
| with self.log_mutex: |
| self.log.extend(new_log) |
| |
| def TestNetLog(host, port): |
| print("Started...") |
| web_log = NetLog(host, port) |
| |
| while True: |
| log = web_log.FetchLog() |
| if log: |
| print(log, end='') |
| time.sleep(.1) |
| |
| |
| def main(argv): |
| parser = argparse.ArgumentParser(description = 'Connects to the weblog.') |
| parser.add_argument('--host', type=str, required = False, |
| default = 'localhost', |
| help = "Example localhost or 1.2.3.4") |
| parser.add_argument('--port', type=int, required = False, default = '49353') |
| args = parser.parse_args(argv) |
| |
| thread = NetLogThread(args.host, args.port) |
| |
| try: |
| while True: |
| print(thread.GetLog(), end='') |
| time.sleep(.1) |
| except KeyboardInterrupt as ki: |
| print("\nUser canceled.") |
| pass |
| |
| print("Waiting to join...") |
| thread.join() |
| return 0 |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv[1:])) |