peter9477

BBPyProject: collect slog2 output and post somewhere

Nov 15th, 2013
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.32 KB | None | 0 0
  1. In app.py:
  2.  
  3.     def onGetDiagnostics(self, mode='recent'):
  4.         try:
  5.             from . import reporting
  6.             diag = reporting.Diagnostics(mode)
  7.             path, length = diag.package()
  8.             tart.send('diagnosticsWritten', path=path, length=length)
  9.  
  10.             status = diag.send()
  11.             tart.send('diagnosticsSent', status=status)
  12.  
  13.         except Exception as ex:
  14.             text = traceback.format_exc()
  15.             tart.send('traceback', text=text)
  16.  
  17. In reporting.py:
  18.  
  19. '''Collection of log files and other info for problem reporting.'''
  20.  
  21. import os
  22. import re
  23. import base64
  24. import datetime as dt
  25. import logging
  26. import pprint
  27. import shutil
  28. import socket
  29. import subprocess
  30. import time
  31. import traceback
  32. import zipfile
  33.  
  34. import tart
  35.  
  36. SLOGGER2_FOLDER = '/tmp/slogger2'
  37. MAX_SANDBOX_LEN = 63
  38.  
  39. try:
  40.     # figure out what our Push target id is
  41.     MANIFEST_PATH = 'app/META-INF/MANIFEST.MF'
  42.     with open(MANIFEST_PATH) as f:
  43.         for line in f:
  44.             if line.startswith('Package-Name:'):
  45.                 PACKAGE_NAME = line.split(None, 1)[1].strip()
  46.                 break
  47. except IOError:
  48.     PACKAGE_NAME = 'TestApp'
  49.  
  50. ZIPPATH = 'tmp/{}.diag.zip'.format(PACKAGE_NAME)
  51.  
  52.  
  53. class Diagnostics:
  54.     def __init__(self, mode='recent'):
  55.         self.mode = mode
  56.  
  57.         self.fzip = zipfile.ZipFile(ZIPPATH, 'w', zipfile.ZIP_DEFLATED)
  58.  
  59.         from http import client
  60.         client.HTTPConnection.debuglevel = 1
  61.  
  62.         # You must initialize logging, otherwise you'll not see debug output.
  63.         logging.basicConfig()
  64.         logging.getLogger().setLevel(logging.DEBUG)
  65.         requests_log = logging.getLogger('requests.packages.urllib3')
  66.         requests_log.setLevel(logging.DEBUG)
  67.         requests_log.propagate = True
  68.  
  69.         from bb.bps import BPS_FAILURE
  70.         from . import netstatus as ns
  71.  
  72.         self.proxies = {}
  73.  
  74.         details = ns.netstatus_proxy_details_t()
  75.         if ns.netstatus_get_proxy_details(details) != BPS_FAILURE:
  76.             if details.http_proxy_host:
  77.                 authority = '{}:{}'.format(
  78.                     details.http_proxy_host.decode('ascii'),
  79.                     details.http_proxy_port)
  80.  
  81.                 if details.http_proxy_login_user:
  82.                     authority = '{}:{}@{}'.format(
  83.                         details.http_proxy_login_user.decode('ascii'),
  84.                         details.http_proxy_login_password.decode('ascii'),
  85.                         authority)
  86.  
  87.                 self.proxies['http'] = authority
  88.                 print('will use proxies', self.proxies)
  89.  
  90.         ns.netstatus_free_proxy_details(details)
  91.  
  92.         self.perimeter = os.environ['PERIMETER']
  93.         self.slog2name = os.path.basename(os.getenv('SANDBOX') or os.getcwd())[:MAX_SANDBOX_LEN]
  94.         print('perimeter', self.perimeter)
  95.         print('slog2name', self.slog2name)
  96.  
  97.  
  98.     def list_logs(self):
  99.         '''Retrieve list of slog2 buffer sets written by the same group id
  100.        as this app is running under, ordered by timestamp.'''
  101.         mygid = os.getgid()
  102.  
  103.         logs = []
  104.         for name in os.listdir(SLOGGER2_FOLDER):
  105.             bpath = os.path.join(SLOGGER2_FOLDER, name)
  106.             stats = os.stat(bpath)
  107.             if stats.st_gid == mygid:
  108.                 logs.append((stats.st_mtime, bpath))
  109.  
  110.         return sorted(logs)
  111.  
  112.  
  113.     def list_session_logs(self):
  114.         '''Filter list of logs by our own process id so we include only the
  115.        current run: assumes pid in filename.'''
  116.         logs = []
  117.         pid = str(os.getpid())
  118.         pattern = '(' + re.escape(self.slog2name) + r'|TartStart\.so)\.(\d+)'
  119.         for mtime, path in list_logs():
  120.             match = re.search(pattern, path)
  121.             if match:
  122.                 if match.group(2) == pid:
  123.                     logs.append((mtime, path))
  124.             else:
  125.                 print('warning: no pid in', path)
  126.  
  127.         return logs
  128.  
  129.  
  130.     def add_logs(self, logs):
  131.         CMD = ['/bin/slog2info', '-l']
  132.         if self.mode == 'recent':
  133.             logs = logs[-6:]
  134.         for mtime, path in logs:
  135.             try:
  136.                 text = subprocess.check_output(CMD + [path])
  137.             except Exception as ex:
  138.                 text = traceback.format_exc()
  139.  
  140.             if isinstance(text, str):
  141.                 text = text.encode('utf-8')
  142.             filename = os.path.basename(path)
  143.             if filename.startswith(self.slog2name):
  144.                 filename = 'session' + filename[len(self.slog2name):]
  145.             zinfo = zipfile.ZipInfo(filename + '.txt',
  146.                 time.localtime(mtime)[:6])
  147.             self.fzip.writestr(zinfo, text)
  148.  
  149.  
  150.     def add_logslog(self):
  151.         '''Add logs/log file'''
  152.         try:
  153.             with open('logs/log', 'rb') as f:
  154.                 data = f.read()
  155.  
  156.             self.fzip.writestr('logs_log.txt', data)
  157.         except IOError:
  158.             pass
  159.             # text = traceback.format_exc()
  160.             # tart.send('traceback', text=text)
  161.  
  162.  
  163.     def add_environ(self):
  164.         text = '\n'.join('{:20} = {}'.format(k, v) for k, v in sorted(dict(os.environ).items()))
  165.         self.fzip.writestr('environ.txt', text)
  166.         tart.send('gotEnviron', text=text)
  167.  
  168.  
  169.     def add_cwd_listing(self):
  170.         CMD = ['ls', '-la']
  171.         try:
  172.             text = subprocess.check_output(CMD)
  173.         except Exception as ex:
  174.             text = traceback.format_exc()
  175.  
  176.         self.fzip.writestr('sandbox-listing.txt', text)
  177.  
  178.  
  179.     def add_pps(self):
  180.         lines = []
  181.         for path in [
  182.             '/pps/system/.all',
  183.             '/pps/services/.all',
  184.             '/pps/services/networking/.all',
  185.             '/pps/services/networking/enterprise/.all',
  186.             '/pps/services/networking/interfaces/.all',
  187.             '/pps/services/networking/all/.all',
  188.             '/pps/services/networking/all/interfaces/.all',
  189.             '/pps/services/wifi/.all',
  190.             '/pps/system/filesystem/local/.all',
  191.             '/pps/system/filesystem/remote/.all',
  192.             '/pps/system/filesystem/remote-enterprise/.all',
  193.             '/pps/system/filesystem/removable/.all',
  194.             ]:
  195.             lines.append('{}:'.format(path))
  196.             try:
  197.                 with open(path) as f:
  198.                     text = f.read()
  199.             except Exception as ex:
  200.                 text = traceback.format_exc()
  201.  
  202.             lines.append(text)
  203.  
  204.         self.fzip.writestr('pps.txt', '\n'.join(lines))
  205.  
  206.  
  207.     def package(self):
  208.         try:
  209.             self.add_environ()
  210.             self.add_cwd_listing()
  211.             self.add_logslog()
  212.             self.add_pps()
  213.  
  214.             logs = self.list_logs()
  215.             # print('logs', logs)
  216.             self.add_logs(logs)
  217.  
  218.         finally:
  219.             self.fzip.close()
  220.  
  221.         return self.fzip.filename, os.stat(self.fzip.filename).st_size
  222.  
  223.  
  224.     def send(self):
  225.         import requests
  226.         from requests.models import PreparedRequest
  227.         from requests.structures import CaseInsensitiveDict
  228.  
  229.         # hot-patch requests to avoid problem with
  230.         def prepare_headers(self, headers):
  231.             if headers:
  232.                 headers = dict((name, value) for name, value in headers.items())
  233.                 self.headers = CaseInsensitiveDict(headers)
  234.             else:
  235.                 self.headers = CaseInsensitiveDict()
  236.  
  237.         PreparedRequest.prepare_headers = prepare_headers
  238.  
  239.  
  240.         from urllib import request
  241.         print('urllib proxies', request.getproxies())
  242.  
  243.         path = self.fzip.filename
  244.  
  245.         headers = {'Content-Type': 'application/octet-stream',
  246.              # 'content-transfer-encoding': 'binary',
  247.              }
  248.  
  249.         proxyDict = self.proxies
  250.  
  251.         saved_to = 'failed!'
  252.         data = open(path, 'rb').read()
  253.  
  254.         ts = dt.datetime.now().strftime('%Y%m%dT%H%M%S')
  255.         name = ts + '-' + os.path.basename(path)
  256.  
  257.         # path = os.path.join('shared/Box/FooBar', name)
  258.         # with open(path, 'wb') as f:
  259.         #     f.write(data)
  260.         #     print('wrote to', path)
  261.         #     saved_to = path
  262.  
  263.         # NOTE: cannot write to /accounts/1000/shared or pshared/ although we can read
  264.  
  265.         # try:
  266.         #     path = os.path.join('shared/misc', name)
  267.         #     with open(path, 'wb') as f:
  268.         #         f.write(data)
  269.         #         print('wrote to', path)
  270.         #         saved_to = path
  271.         # except IOError:
  272.         #     text = traceback.format_exc()
  273.         #     # tart.send('traceback', text=text)
  274.  
  275.         #     tart.send('traceback', text=text)
  276.  
  277.         params = {'filename': name}
  278.  
  279.         try:
  280.             print('trying server')
  281.             url = 'http://example.com:8080/cgi-bin/savediag.py'
  282.             r = requests.post(url,
  283.                 params=params,
  284.                 headers=headers,
  285.                 proxies=proxyDict,
  286.                 data=data, # base64.b64encode(data),
  287.                 timeout=32,
  288.                 )
  289.             print('example.com', r.status_code)
  290.             print('headers:', pprint.pformat(dict(r.headers.items())))
  291.             print('body:', r.text)
  292.             saved_to = 'example.com'
  293.  
  294.         except Exception as ex:
  295.             text = traceback.format_exc()
  296.             print('error', text)
  297.  
  298.         print('returning')
  299.         return saved_to
  300.  
  301.  
  302. # EOF
  303.  
  304. If you need netstatus, which isn't in tart/python/bb as of this moment:
  305.  
  306. '''Wrappers for netstatus routines'''
  307.  
  308. import ctypes
  309. from ctypes import (c_bool, c_float, c_double, c_int, c_char, c_char_p, c_void_p, c_uint,
  310.    POINTER, Structure, CFUNCTYPE)
  311.  
  312. from bb._wrap import _func, _register_funcs
  313.  
  314. NETSTATUS_INFO = 0x01
  315.  
  316. class netstatus_proxy_details_t(Structure):
  317.    _fields_ = [
  318.        ('http_proxy_host', c_char_p),
  319.        ('http_proxy_port', c_int),
  320.        ('https_proxy_host', c_char_p),
  321.        ('https_proxy_port', c_int),
  322.        ('ftp_proxy_host', c_char_p),
  323.        ('ftp_proxy_port', c_int),
  324.        ('http_proxy_login_user', c_char_p),
  325.        ('http_proxy_login_password', c_char_p),
  326.        ]
  327.  
  328. class netstatus_interface_list_t(Structure):
  329.    _fields_ = [
  330.        ('num_interfaces', c_int),
  331.        ('interfaces', POINTER(c_char_p)),
  332.        ]
  333.  
  334. NETSTATUS_INTERFACE_TYPE_UNKNOWN       = 0
  335. NETSTATUS_INTERFACE_TYPE_WIRED         = 1
  336. NETSTATUS_INTERFACE_TYPE_WIFI          = 2
  337. NETSTATUS_INTERFACE_TYPE_BLUETOOTH_DUN = 3
  338. NETSTATUS_INTERFACE_TYPE_USB           = 4
  339. NETSTATUS_INTERFACE_TYPE_VPN           = 5
  340. NETSTATUS_INTERFACE_TYPE_BB            = 6
  341. NETSTATUS_INTERFACE_TYPE_CELLULAR      = 7
  342. netstatus_interface_type_t = c_int
  343.  
  344. NETSTATUS_IP_STATUS_ERROR_UNKNOWN        = 0
  345. NETSTATUS_IP_STATUS_OK                   = 1
  346. NETSTATUS_IP_STATUS_ERROR_NOT_CONNECTED  = 2
  347. NETSTATUS_IP_STATUS_ERROR_NOT_UP         = 3
  348. NETSTATUS_IP_STATUS_ERROR_NOT_CONFIGURED = 4
  349. NETSTATUS_IP_STATUS_ERROR_IP6_OFF        = 5
  350. NETSTATUS_IP_STATUS_ERROR_NO_IP_ADDRESS  = 6
  351. NETSTATUS_IP_STATUS_ERROR_NO_IP6_ADDRESS = 7
  352. NETSTATUS_IP_STATUS_ERROR_NO_IP_GATEWAY  = 8
  353. NETSTATUS_IP_STATUS_ERROR_NO_IP6_GATEWAY = 9
  354. NETSTATUS_IP_STATUS_ERROR_NO_NAME_SERVER = 10
  355. netstatus_ip_status_t = c_int
  356.  
  357. # BPS_API int netstatus_request_events(int flags);
  358. # BPS_API int netstatus_stop_events(int flags);
  359. # BPS_API int netstatus_get_domain();
  360. # BPS_API int netstatus_get_availability(bool *is_available);
  361. # BPS_API int netstatus_get_default_interface(char **interface);
  362. netstatus_get_proxy_details = _func(c_int, POINTER(netstatus_proxy_details_t))
  363. # BPS_API int netstatus_get_proxy_details_for_url(const char *url, const char *interface, netstatus_proxy_details_t *details);
  364. netstatus_free_proxy_details = _func(None, POINTER(netstatus_proxy_details_t))
  365. # BPS_API bool netstatus_event_get_availability(bps_event_t *event);
  366. # BPS_API const char * netstatus_event_get_default_interface(bps_event_t *event);
  367. # BPS_API bool netstatus_event_get_http_proxy_login_required(bps_event_t *event);
  368. # BPS_API const char * netstatus_event_get_http_proxy_host(bps_event_t *event);
  369. # BPS_API int netstatus_event_get_http_proxy_port(bps_event_t *event);
  370. # BPS_API const char * netstatus_event_get_https_proxy_host(bps_event_t *event);
  371. # BPS_API int netstatus_event_get_https_proxy_port(bps_event_t *event);
  372. # BPS_API const char * netstatus_event_get_ftp_proxy_host(bps_event_t *event);
  373. # BPS_API int netstatus_event_get_ftp_proxy_port(bps_event_t *event);
  374. # BPS_API int netstatus_get_interfaces(netstatus_interface_list_t *interface_list);
  375. # BPS_API void netstatus_free_interfaces(netstatus_interface_list_t *interface_list);
  376. # BPS_API int netstatus_get_interface_details(const char *interface, netstatus_interface_details_t **details);
  377. # BPS_API void netstatus_free_interface_details(netstatus_interface_details_t **details);
  378. # BPS_API const char * netstatus_interface_get_name(netstatus_interface_details_t *details);
  379. # BPS_API netstatus_interface_type_t netstatus_interface_get_type(netstatus_interface_details_t *details);
  380. # BPS_API bool netstatus_interface_is_connected(netstatus_interface_details_t *details);
  381. # BPS_API bool netstatus_interface_is_up(netstatus_interface_details_t *details);
  382. # BPS_API netstatus_ip_status_t netstatus_interface_get_ip_status(netstatus_interface_details_t *details);
  383. # BPS_API netstatus_ip_status_t netstatus_interface_get_ip6_status(netstatus_interface_details_t *details);
  384. # BPS_API int netstatus_interface_get_num_ip_addresses(netstatus_interface_details_t *details);
  385. # BPS_API const char * netstatus_interface_get_ip_address(netstatus_interface_details_t *details, int index);
  386. # BPS_API const char * netstatus_interface_get_ip_address_netmask(netstatus_interface_details_t *details, int index);
  387. # BPS_API const char * netstatus_interface_get_ip_broadcast_address(netstatus_interface_details_t *details);
  388. # BPS_API int netstatus_interface_get_num_ip_gateways(netstatus_interface_details_t *details);
  389. # BPS_API const char * netstatus_interface_get_ip_gateway(netstatus_interface_details_t *details, int index);
  390. # BPS_API const char * netstatus_interface_get_link_address(netstatus_interface_details_t *details);
  391. # BPS_API int netstatus_interface_get_num_name_servers(netstatus_interface_details_t *details);
  392. # BPS_API const char * netstatus_interface_get_name_server(netstatus_interface_details_t *details, int index);
  393. # BPS_API const char * netstatus_interface_get_search_domains(netstatus_interface_details_t *details);
  394.  
  395. from bb.bps import _dll
  396. _register_funcs(_dll, globals(), True)
Add Comment
Please, Sign In to add comment