1# Copyright 2020, Google Inc. 2# All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are 6# met: 7# 8# * Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# * Redistributions in binary form must reproduce the above 11# copyright notice, this list of conditions and the following disclaimer 12# in the documentation and/or other materials provided with the 13# distribution. 14# * Neither the name of Google Inc. nor the names of its 15# contributors may be used to endorse or promote products derived from 16# this software without specific prior written permission. 17# 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29"""Server related utilities.""" 30 31from __future__ import absolute_import 32 33import logging 34import logging.handlers 35import threading 36import time 37 38from mod_pywebsocket import common 39from mod_pywebsocket import util 40 41 42def _get_logger_from_class(c): 43 return logging.getLogger('%s.%s' % (c.__module__, c.__name__)) 44 45 46def configure_logging(options): 47 logging.addLevelName(common.LOGLEVEL_FINE, 'FINE') 48 49 logger = logging.getLogger() 50 logger.setLevel(logging.getLevelName(options.log_level.upper())) 51 if options.log_file: 52 handler = logging.handlers.RotatingFileHandler(options.log_file, 'a', 53 options.log_max, 54 options.log_count) 55 else: 56 handler = logging.StreamHandler() 57 formatter = logging.Formatter( 58 '[%(asctime)s] [%(levelname)s] %(name)s: %(message)s') 59 handler.setFormatter(formatter) 60 logger.addHandler(handler) 61 62 deflate_log_level_name = logging.getLevelName( 63 options.deflate_log_level.upper()) 64 _get_logger_from_class(util._Deflater).setLevel(deflate_log_level_name) 65 _get_logger_from_class(util._Inflater).setLevel(deflate_log_level_name) 66 67 68class ThreadMonitor(threading.Thread): 69 daemon = True 70 71 def __init__(self, interval_in_sec): 72 threading.Thread.__init__(self, name='ThreadMonitor') 73 74 self._logger = util.get_class_logger(self) 75 76 self._interval_in_sec = interval_in_sec 77 78 def run(self): 79 while True: 80 thread_name_list = [] 81 for thread in threading.enumerate(): 82 thread_name_list.append(thread.name) 83 self._logger.info("%d active threads: %s", 84 threading.active_count(), 85 ', '.join(thread_name_list)) 86 time.sleep(self._interval_in_sec) 87 88 89# vi:sts=4 sw=4 et 90