From 7c76d131110e4641114e3066844e7195efb2f33b Mon Sep 17 00:00:00 2001 From: Jan Lehnardt Date: Tue, 12 May 2009 19:36:15 +0000 Subject: Add non-streaming log-file handler. A GET request to /_log will show the last 1000 bytes of the logflie. More bytes can be requested with GET /_log?bytes=10000. git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@774045 13f79535-47bb-0310-9956-ffa450edef68 --- etc/couchdb/default.ini.tpl.in | 1 + src/couchdb/couch_httpd_misc_handlers.erl | 14 +++++++++++++- src/couchdb/couch_log.erl | 14 ++++++++++++++ src/couchdb/couch_util.erl | 10 ++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/etc/couchdb/default.ini.tpl.in b/etc/couchdb/default.ini.tpl.in index 337886e1..3caaf597 100644 --- a/etc/couchdb/default.ini.tpl.in +++ b/etc/couchdb/default.ini.tpl.in @@ -59,6 +59,7 @@ _replicate = {couch_httpd_misc_handlers, handle_replicate_req} _uuids = {couch_httpd_misc_handlers, handle_uuids_req} _restart = {couch_httpd_misc_handlers, handle_restart_req} _stats = {couch_httpd_stats_handlers, handle_stats_req} +_log = {couch_httpd_misc_handlers, handle_log_req} [httpd_db_handlers] _compact = {couch_httpd_db, handle_compact_req} diff --git a/src/couchdb/couch_httpd_misc_handlers.erl b/src/couchdb/couch_httpd_misc_handlers.erl index d03cbd3f..92e0252a 100644 --- a/src/couchdb/couch_httpd_misc_handlers.erl +++ b/src/couchdb/couch_httpd_misc_handlers.erl @@ -14,7 +14,7 @@ -export([handle_welcome_req/2,handle_favicon_req/2,handle_utils_dir_req/2, handle_all_dbs_req/1,handle_replicate_req/1,handle_restart_req/1, - handle_uuids_req/1,handle_config_req/1, + handle_uuids_req/1,handle_config_req/1,handle_log_req/1, handle_task_status_req/1]). -export([increment_update_seq_req/2]). @@ -195,3 +195,15 @@ increment_update_seq_req(#httpd{method='POST'}=Req, Db) -> increment_update_seq_req(Req, _Db) -> send_method_not_allowed(Req, "POST"). +% httpd log handlers + +handle_log_req(#httpd{method='GET'}=Req) -> + LastBytes = list_to_integer(couch_httpd:qs_value(Req, "bytes", "1000")), + {ok, Resp} = start_chunked_response(Req, 200, [ + % send a plaintext response + {"Content-Type", "text/plain; charset=utf-8"} + ]), + send_chunk(Resp, couch_log:read(LastBytes)), + send_chunk(Resp, ""); +handle_log_req(Req) -> + send_method_not_allowed(Req, "GET"). diff --git a/src/couchdb/couch_log.erl b/src/couchdb/couch_log.erl index 3d99ae1e..693eed9b 100644 --- a/src/couchdb/couch_log.erl +++ b/src/couchdb/couch_log.erl @@ -16,6 +16,7 @@ -export([start_link/0,stop/0]). -export([debug_on/0,info_on/0,get_level/0,get_level_integer/0, set_level/1]). -export([init/1, handle_event/2, terminate/2, code_change/3, handle_info/2, handle_call/2]). +-export([read/1]). -define(LEVEL_ERROR, 3). -define(LEVEL_INFO, 2). @@ -120,3 +121,16 @@ log(Fd, Pid, Level, Format, Args) -> ok = io:format("[~s] [~p] ~s~n", [Level, Pid, Msg]), % dump to console too {ok, Msg2, _} = regexp:gsub(lists:flatten(Msg),"\\r\\n|\\r|\\n", "\r\n"), ok = io:format(Fd, "[~s] [~s] [~p] ~s\r~n\r~n", [httpd_util:rfc1123_date(), Level, Pid, Msg2]). + +read(LastBytes) -> + LogFileName = couch_config:get("log", "file"), + LogFileSize = couch_util:file_read_size(LogFileName), + + {ok, Fd} = file:open(LogFileName, [binary]), + Start = lists:max([LogFileSize - LastBytes, 0]), + + % TODO: truncate chopped first line + % TODO: make streaming + + {ok, Chunk} = file:pread(Fd, Start, LogFileSize), + Chunk. diff --git a/src/couchdb/couch_util.erl b/src/couchdb/couch_util.erl index a119cf1c..0a715520 100644 --- a/src/couchdb/couch_util.erl +++ b/src/couchdb/couch_util.erl @@ -17,8 +17,10 @@ -export([new_uuid/0, rand32/0, implode/2, collate/2, collate/3]). -export([abs_pathname/1,abs_pathname/2, trim/1, ascii_lower/1]). -export([encodeBase64/1, decodeBase64/1, to_hex/1,parse_term/1,dict_find/3]). +-export([file_read_size/1]). -include("couch_db.hrl"). +-include_lib("kernel/include/file.hrl"). % arbitrarily chosen amount of memory to use before flushing to disk -define(FLUSH_MAX_MEM, 10000000). @@ -291,3 +293,11 @@ dict_find(Key, Dict, DefaultValue) -> error -> DefaultValue end. + + +file_read_size(FileName) -> + case file:read_file_info(FileName) of + {ok, FileInfo} -> + FileInfo#file_info.size; + Error -> Error + end. -- cgit v1.2.3