1:- module(jsonrpc_logging, [
    2  set_jsonrpc_log_directory/1,
    3  get_jsonrpc_log_directory/1,
    4
    5  enable_jsonrpc_logging/1,
    6  enable_jsonrpc_logging/0,
    7
    8  disable_jsonrpc_logging/0,
    9  clear_jsonrpc_logs/0,
   10
   11  enable_jsonrpc_tracing/0,
   12  disable_jsonrpc_tracing/0,
   13  get_jsonrpc_tracing/1,
   14  set_jsonrpc_tracing/1
   15  ]).   16
   17:- use_module(library(filesex)).   18:- use_module(library(log4p)).   19:- use_module(library(http/json)).   20
   21:- dynamic jsonrpc_log_directory/1.   22:- dynamic jsonrpc_log_enabled/0.   23:- dynamic jsonrpc_trace_enabled/0.   24
   25set_jsonrpc_log_directory(LogDirectory) :-
   26  retractall(jsonrpc_log_directory(_)),
   27  assertz(jsonrpc_log_directory(LogDirectory)),
   28  debug("JSON-RPC log directory set to %w",[LogDirectory]).
   29
   30get_jsonrpc_log_directory(LogDirectory) :-
   31  jsonrpc_log_directory(LogDirectory).
   32
   33enable_jsonrpc_logging(LogDirectory) :-
   34  set_jsonrpc_log_directory(LogDirectory),
   35  enable_jsonrpc_logging.
   36
   37enable_jsonrpc_logging :-
   38  jsonrpc_log_enabled, !.
   39
   40enable_jsonrpc_logging :-
   41  assertz(jsonrpc_log_enabled),
   42  debug("JSON_RPC logging enabled").
   43
   44disable_jsonrpc_logging :-
   45  retractall(jsonrpc_log_enabled),
   46  debug("JSON_RPC logging disabled").
   47
   48clear_jsonrpc_logs :-
   49  get_jsonrpc_log_directory(LogDirectory),
   50  delete_directory_contents(LogDirectory).
   51
   52enable_jsonrpc_tracing :-
   53  assertz(jsonrpc_trace_enabled),
   54  debug("JSON_RPC tracing enabled").
   55
   56disable_jsonrpc_tracing :-
   57  retractall(jsonrpc_trace_enabled),
   58  debug("JSON_RPC tracing disabled").
   59
   60get_jsonrpc_tracing(enabled) :-
   61  tracing_enabled, !.
   62
   63get_jsonrpc_tracing(disabled).
   64
   65set_jsonrpc_tracing(enabled) :-
   66  enable_jsonrpc_tracing.
   67
   68set_jsonrpc_tracing(disabled) :-
   69  disable_jsonrpc_tracing.
   70
   71% -- hooks ---
   72
   73jsonrpc_protocol:on_message_read(Message) :-
   74  log_message(Message, request).
   75
   76jsonrpc_protocol:on_message_write(Message) :-
   77  log_message(Message, response).
   78
   79jsonrpc_protocol:on_message_read(Message) :-
   80  trace_message(Message, request).
   81
   82jsonrpc_protocol:on_message_write(Message) :-
   83  trace_message(Message, response).
   84
   85% --- helpers ---
   86
   87log_message(Message, Kind) :-
   88  logging_enabled,
   89  build_filename(Kind, FileName),
   90  get_jsonrpc_log_directory(LogDirectory),
   91  (exists_directory(LogDirectory) 
   92    -> true
   93    ; make_directory(LogDirectory) 
   94    ),
   95  absolute_file_name(FileName, Absolute, [relative_to(LogDirectory)]),
   96  atom_json_dict(Content, Message, [as(string)]),
   97  setup_and_call_cleanup(
   98    open(Absolute, write, Out, [create([read,write])]),
   99    write(Out, Content),
  100    close(Out)
  101    ).
  102
  103build_filename(Kind, FileName) :-
  104  get_time(Timestamp),
  105  format_time(string(TSString), '%Y%m%d_%H%M%S',Timestamp),
  106  swritef(FileName,"%w.%w.log.json",[TSString, Kind]).
  107
  108logging_enabled :-
  109  jsonrpc_log_enabled,
  110  jsonrpc_log_directory(LogDirectory),
  111  ground(LogDirectory).
  112
  113trace_message(Message, request) :-
  114  tracing_enabled,
  115  atom_json_dict(Content, Message, [as(string)]),
  116  log4p:info('received %w', [Content]).
  117
  118trace_message(Message, response) :-
  119  tracing_enabled,
  120  atom_json_dict(Content, Message, [as(string)]),
  121  log4p:info('sent %w', [Content]).
  122
  123tracing_enabled :-
  124  jsonrpc_trace_enabled