2015-06-26 21 views
9

Trong một dự án python với nhiều chủ đề đăng nhập của tôi hoạt động tốt để ghi vào một tệp nhật ký. Về cơ bản, dựa trên Logging, StreamHandler and standard streamspython chai luôn luôn đăng nhập vào giao diện điều khiển, không đăng nhập vào tập tin

Một phần của dự án của tôi là máy chủ web dạng chai chạy tốt. Nhưng mỗi cuộc gọi chai viết nhật ký cho bảng điều khiển như sau:

192.168.178.20 - - [26/Jun/2015 20:22:17] "GET /edit?addJob HTTP/1.1" 200 48028 

Làm cách nào để xử lý mã này giống như mã khác?

+0

Bạn chấp nhận câu trả lời của ayb, nhưng hãy cân nhắc việc thay đổi câu trả lời đó. Không cần chấp nhận tôi (trừ khi bạn nghĩ đó là câu trả lời chính xác nhất), nhưng tôi không muốn thấy khách truy cập trong tương lai câu hỏi này bị lừa bởi mã của ayb, không nên được sử dụng ngoại trừ trong các ứng dụng nhẹ nhất (và thậm chí sau đó , đó là một thực tế có vấn đề). –

Trả lời

3

Nếu bạn đang lăn giải pháp của riêng bạn, bạn nên viết một plugin Chai đơn giản mà phát ra dòng nhật ký để một logger logging. Dưới đây là ví dụ thiết lập trình ghi nhật ký cơ bản, xác định plugin ghi nhật ký và tạo ứng dụng Chai có plugin được cài đặt trên tất cả các tuyến.

from bottle import Bottle, request, response 
from datetime import datetime 
from functools import wraps 
import logging 

logger = logging.getLogger('myapp') 

# set up the logger 
logger.setLevel(logging.INFO) 
file_handler = logging.FileHandler('myapp.log') 
formatter = logging.Formatter('%(msg)s') 
file_handler.setLevel(logging.DEBUG) 
file_handler.setFormatter(formatter) 
logger.addHandler(file_handler) 

def log_to_logger(fn): 
    ''' 
    Wrap a Bottle request so that a log line is emitted after it's handled. 
    (This decorator can be extended to take the desired logger as a param.) 
    ''' 
    @wraps(fn) 
    def _log_to_logger(*args, **kwargs): 
     request_time = datetime.now() 
     actual_response = fn(*args, **kwargs) 
     # modify this to log exactly what you need: 
     logger.info('%s %s %s %s %s' % (request.remote_addr, 
             request_time, 
             request.method, 
             request.url, 
             response.status)) 
     return actual_response 
    return _log_to_logger 

app = Bottle() 
app.install(log_to_logger) 

@app.route('/') 
def home(): 
    return ['hello, world'] 

app.run(host='0.0.0.0', port='8080', quiet=True) 

Chạy mã mà mang lại những gì bạn muốn:

% python myapp.py & 
% curl -v http://localhost:8080/ 
% tail myapp.log  
127.0.0.1 2015-06-27 16:57:09.983249 GET http://localhost:8080/ 200 OK 
+0

Được thử nghiệm, hoạt động! Sẽ thêm một số câu lệnh để một 'bản in' bình thường cũng sẽ đăng nhập vào tệp. – gNeandr

+0

Xin chúc mừng! –

+0

Bạn đã xóa 'bản in' tôi đã thêm chưa? Tôi đang cố gắng sử dụng giải pháp của bạn khi bắt đầu chương trình chai trên một chuỗi ... sẽ đăng nó dưới – gNeandr

-2

Bạn đang chạy máy chủ nội bộ phải không? Sau đó, bạn có thể làm cho một plugin đơn giản:

from bottle import request, response, route, install, run 
from datetime import datetime 


def logger(func): 
    def wrapper(*args, **kwargs): 
     log = open('log.txt', 'a') 
     log.write('%s %s %s %s %s \n' % (request.remote_addr, datetime.now().strftime('%H:%M'), 
             request.method, request.url, response.status)) 
     log.close() 
     req = func(*args, **kwargs) 
     return req 
    return wrapper 

install(logger) 


@route('/') 
def index(): 
    return 'Hello, World' 

run(quiet=True) 

Hoặc thử this one

+0

Có, nó hoạt động. Nhưng tôi thấy một cuộc xung đột vì cách giải pháp này ghi vào nhật ký sẽ được ghi vào cùng một tệp nhật ký như với phần chính của dự án (xem liên kết được tham chiếu ở trên). Các dự án chai được bắt đầu trên một trong một số chủ đề và tôi nghĩ rằng "bản ghi chai" nên được xử lý bởi phần dự án chính cũng có. – gNeandr

+1

CẢNH BÁO: không làm điều này, trừ khi bạn thực sự không quan tâm đến hiệu suất. Mã này sẽ mở một tệp trên * mọi yêu cầu duy nhất, đó là một ý tưởng khủng khiếp. –

+0

vâng, nó không phải là về sự hoàn hảo, nó chỉ là một khái niệm – ayb

0

Tôi đang cố gắng để sử dụng giải pháp của Ron với khởi động chương trình bình trên một sợi:

tWeb = Thread(target=runWeb, args=('192.168.178.16', 5003)).start() 

với

def runWeb(aserver, aport): 
    run(host=aserver, port=aport, debug=True) 

nhưng điều đó không thành công. Bất kỳ 'in' nào đi vào tệp, nhưng không phải là 'lợi nhuận' (xem ở trên), nó sẽ chuyển đến bảng điều khiển.

Thay đổi "debug = True" thành "quiet = True" chỉ thay đổi thành: không có đầu ra nào trên bảng điều khiển.

+0

@Ron Bất kỳ ý tưởng nào ngăn cản việc xuất 'lợi nhuận' vào tệp nhật ký? – gNeandr

+0

Bạn đang nói về năng suất nào? Tôi không thấy sản lượng ở đâu cả. –

+0

Upps, vui lòng xem nhận xét của bạn "Chạy mã đó mang lại những gì bạn muốn" ở trên ... một phần của nó bạn đã đăng "127.0.0.1 2015-06-27 16: 57: 09.983249 NHẬN http: // localhost: 8080/200 OK "... và đó là những gì tôi đang thiếu khi bắt đầu phần chai trong một sợi .. xem câu trả lời của tôi ở trên. – gNeandr

Các vấn đề liên quan