logger_service.anubis 11.2 KB
/*
 * 
 * User: David RENE
 * Date: 29/07/2007
 * Time: 02:04
 * (c) Calexium
 *
 */

read tools/basis.anubis
read system/muscle.anubis
read system/data_io.anubis
read system/convert.anubis
read system/string.anubis
read system/logger.anubis
read system/message_queue.anubis
read system/message_transceiver.anubis

read calexium_lib/CXM_message_constants.anubis
read calexium_lib/net_services/CXM_net_services.anubis
read calexium_lib/net_services/CXM_generic_protocol.anubis

// Special non-existing file. This is a work arround for a impossibility to define global configuration in anubis.
// So this file allows you to specify on which UDP port the logger server is listening.
// You have to provide this file in your base source directory (or any other folder which is scanned by the compilater,
// and you define a function named 'logger_port' which simply return the port number as an Int32.
// Example: 
//     public define Int32 logger_port = 33610.
read logger_config.anubis

public define Int32 logger_srv_version = 1.

  /** 
   *  has_update scan the given message for finding corresponding available update
   *  package for the application. The request message come with AppId field which contain
   *  package or application signature and CurrentVersion field which is current version
   *  installed on the requester.
   * 
   * --- REQUEST message format
   *  msg [_CXM_UPD_HAS_UPDATE]
   *      string "AppId" = hash or unique signature of the package
   *      string "CurrentVersion" = current version installed on the remote caller
   * 
   * --- ANSWER message format
   *  
   *  ERROR case message format 
   *  msg [_CXM_ACK]
   *      int32 "CMD" = _CXM_UPD_HAS_UPDATE
   *      int32 "STATUS" = _CXM_ERROR
   *  
   *  OK without update available
   *  msg [_CXM_ACK]
   *      int32 "CMD"    = _CXM_UPD_HAS_UPDATE
   *      int32 "STATUS" = _CXM_OK
   *      msg "RESULT" [_CXM_ACK_RESULT_MSG] 
   *          int32 "PackageStatus" = no_update // numerical value = 0
   * 
   */
   
define Bool 
  process_log
  (
    Logger    log,
    Message   msg
  )=
  if find_string(msg, "LogString") is
  {
    failure         then logError(log, "process_log can't find LogString");false,
    success(log_string) then
    if find_int32(msg, "Level") is
    {
      failure         then logError(log, "process_log can't find Level");false,
      success(int_level)  then
        if find_int32(msg, "Thread") is
        {
          failure         then logError(log, "process_log can't find Level");false,
          success(thread_id)  then
            with level = get_LogLevel_from_value(int_level),
            if level is logTrace then
                if find_string(msg, "LogMask") is
                {
                  failure           then logError(log, "process_log can't find LogMask");false,
                  success(log_mask) then logTrace(log, logMask(log_mask), log_string, thread_id); true
                }
            else doLog(log, log_string, level, thread_id); true
//            {
//              logNone           then  true,
//              logCriticalError  then  logCriticalError(log, log_string); true,
//              logError          then  logError(log, log_string); true,
//              logWarning        then  logWarning(log, log_string); true,
//              logInfo           then  logInfo(log, log_string); true,
//              logDebug          then  logDebug(log, log_string); true
//              logTrace          then  
//                if find_string(msg, "LogMask") is
//                {
//                  failure           then logError(log, "process_log can't find LogMask");false,
//                  success(log_mask) then logTrace(log, logMask(log_mask),log_string); true
//                }
//            }
        }
    }
	}.

define Bool 
  process_log
  (
    List(Logger)    logs,
    Message         msg
  )=
  if find_string(msg, "LogName") is
  {
    failure         then println("process_log can't find LogName");false,
    success(log_name) then
    if get_logger(logs, log_name) is
    {
      failure       then  println("can't find log ["+log_name+"]");false,
      success(log)  then 	process_log(log, msg)
    }
  }.
  
  /** message_received is the principal 
   */
 /*
 define One
  message_received
  (
    MessageQueue    queue,
    List(Logger)    logs,
    Message         msg
  )=
  with msg_what = *msg.what,
  if msg_what = _CXM_LOGGER_LOG then
    send_result(queue, _CXM_LOGGER_LOG, process_log(logs, msg))
  else
    println("wrong message_received is not _CXM_LOGGER_LOG ");unique
  .
  
 define One
  logger_handler
  (
    MessageQueue    queue,
    List(Logger)    logs
  )=
  if queue.get_next_received_Message(1) is
  {
    timeout   then  //println("logger_handler timeout ["+queue.get_name(unique)+"]");
      logger_handler(queue, logs),
    closed    then  //println("logger_handler closed ["+queue.get_name(unique)+"]");
      unique,
    msg(msg)  then  //println("logger_handler msg received ["+queue.get_name(unique)+"]");
      message_received(queue, logs, msg);
      logger_handler(queue, logs)
  }.

 public define NetService
  logger_service
  (
    List(Logger) logs
  )=
    net_service(
                logger_srv_version, 
                _CXM_LOGGER_SERVICE_ID, //id of the service declared in CXM_message_constants
                "Logger service",       //human readable name of the service
                (
                  MessageQueue queue,
                  String       peer
                ) |-> logger_handler(queue, logs)).

 */
 /****************** LOCAL UDP SERVICE *************/
 

public define String 
  data_preview
  (
    ByteArray data,
    Int32     max
  ) =
  with l = length(data),
       firsts_bytes = extract(data, 0, max),
  "Length=" + l + "; String='"+to_string(firsts_bytes)+"' Buffer=[" + to_ascii(firsts_bytes) + (if l > max then "...]" else "]").

 
define 	(UDP_Socket, ByteArray, Truncation, Int32, Int32) -> One
  make_udp_handler
    (
       List(Logger) logs,
       Logger       debug_logger
	  ) =
	(	
		UDP_Socket 	socket,
    ByteArray 	data,
    Truncation	truncation, 
    Int32   		ip_address,
    Int32   		ip_port
	)	 |->
	with ip = ip_addr_to_string(ip_address),
	logTrace(debug_logger, logMask("Logger"), "LoggerServer: data received (" + length(data) + " bytes) from IP " + ip + "... ");
	if receive_message_from_io(make_data_io(data)) is
	{
		failure 			then logWarning(debug_logger, "LoggerServer: Bad data packet received from IP " + ip + ": " + data_preview(data, 20)),
		success(msg)	then
      if *msg.what = _CXM_LOGGER_LOG then
        forget(process_log(logs, msg))
      else
        println("LoggerService: wrong message_received. [" + to_hexa(*msg.what) + "] is not _CXM_LOGGER_LOG ")
	}.
	  
define One
  my_notify
     (
       One dummy
     ) =
    unique.

public define Maybe(UDP_Server)
   start_logger_server
     (
       List(Logger) logs,
       Logger       debug_logger
     ) =
  if start_udp_server(0,
                      logger_port, 
                      make_udp_handler(logs, debug_logger),
                      8*1024,
                      my_notify) is
  {
    cannot_create_the_socket then logError(debug_logger, "Cannot create the listening socket."); failure, 
    cannot_bind_address_port then logError(debug_logger, "Cannot bind to port " + logger_port + ".");failure,
    access_denied            then logError(debug_logger, "Cannot listen on port " + logger_port + ".");failure,
    ok(server)               then logInfo(debug_logger, "LocalLog Server started on port " + logger_port + "."); success(server)
  }.
   

 /****************** CLIENT PART *******************/
 
/*
 define One
  send_log_msg
  (
    MessageQueue  queue,
    Message       log_msg
  )=
  with test_msg = message(_CXM_REQUEST_FOR_SERVICE),
  forget(add_int32(test_msg, "service", _CXM_LOGGER_SERVICE_ID));
  forget(add_int32(test_msg, "version", 1));
  queue.add_Message_to_send(test_msg);
  if queue.get_next_received_Message(30) is
  {
    timeout then println("send_log_msg receive timeout"),
    closed  then println("send_log_msg socket closed"),
    msg(msg)  then 
      if find_int32(msg, "STATUS") is
      {
        failure     then println("status not found"),
        success(v)  then 
          if v = _CXM_OK then 
            queue.add_Message_to_send(log_msg);
            forget(wait_for_reply(queue, _CXM_LOGGER_LOG, 30))
          else
            println("requested service started won't start")        
      }
  }.
*/  

define One
  local_net_logger
  (
    String  logger_server,
    Message log_message
  )=
  forget(send_message_by_udp(log_message, ip_address((127,0,0,1)), logger_port)).
  
/*  if find_string(log_message, "LogString") is
  {
    failure         then println("process_log can't find LogString"),
    success(log_string) then println(log_string)
  }.
  if connect( ip_address((127,0,0,1)), 33125) is
  {
    error(_)  then println("can't connect to logger server ["+logger_server+"]");
    							 forget(process_log(fullLogger, log_message)),
    ok(conn)  then 
      with queue = create_MessageQueue("net logger sender"),
      message_transceiver(conn, queue);
      send_log_msg(queue, log_message);
      queue.quit(unique)
  }.*/

define Message
  create_log_msg
  (
    String  logger_name,
    String  log_string,
    Int32   level
  )=
  with string = if length(log_string) > 1024 then (if sub_string(log_string, 0, 1024) is success(s) then s else "?") + "..."
                                             else log_string,
  with log_msg = message(_CXM_LOGGER_LOG),
  forget(add_string(log_msg, "LogName", logger_name));
  forget(add_string(log_msg, "LogString", string));
  forget(add_int32(log_msg, "Level", level));
  forget(add_int32(log_msg, "Thread", virtual_machine_id));
  log_msg
  .

public define One 
  logNone( 
    String logger_name, 
    String log_string
  )=
  local_net_logger("127.0.0.1", create_log_msg(logger_name, log_string, 0)).

public define One 
  logCriticalError( 
    String logger_name, 
    String log_string
  )=
  local_net_logger("127.0.0.1", create_log_msg(logger_name, log_string, 1)).

public define One 
  logError( 
    String logger_name, 
    String log_string
  )=
  local_net_logger("127.0.0.1", create_log_msg(logger_name, log_string, 2)).

public define One 
  logWarning( 
    String logger_name, 
    String log_string
  )=
  local_net_logger("127.0.0.1", create_log_msg(logger_name, log_string, 3)).
  
public define One 
  logInfo( 
    String logger_name, 
    String log_string
  )=
  local_net_logger("127.0.0.1", create_log_msg(logger_name, log_string, 4)).

public define One 
  logDebug( 
    String logger_name, 
    String log_string
  )=
  local_net_logger("127.0.0.1", create_log_msg(logger_name, log_string, 5)).

public define One 
  logTrace( 
    String  logger_name,
    LogMask log_mask,
    String  log_string
  )=
  with log_msg = create_log_msg(logger_name, log_string, 6),
  forget(add_string(log_msg, "LogMask", log_mask.mask));
  local_net_logger("127.0.0.1", log_msg).