text: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
   * Copyright by The HDF Group.                                               *
   * Copyright by the Board of Trustees of the University of Illinois.         *
   * All rights reserved.                                                      *
   *                                                                           *
   * This file is part of HDF5.  The full HDF5 copyright notice, including     *
   * terms governing use, modification, and redistribution, is contained in    *
   * the COPYING file, which can be found at the root of the source code       *
   * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
   * If you do not have access to either file, you may request a copy from     *
   * help@hdfgroup.org.                                                        *
   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  
  /*-------------------------------------------------------------------------
   *
   * Created:     H5Clog_json.c
   *
   * Purpose:     Cache log implementation that emits JSON-formatted log
   *              entries for consumption by new-fangled data analysis tools.
   *
   *-------------------------------------------------------------------------
   */
  
  /****************/
  /* Module Setup */
  /****************/
  #include "H5Cmodule.h" /* This source code file is part of the H5C module */
  
  /***********/
  /* Headers */
  /***********/
  #include "H5private.h"   /* Generic Functions                        */
  #include "H5Cpkg.h"      /* Cache                                    */
  #include "H5Clog.h"      /* Cache logging                            */
  #include "H5Eprivate.h"  /* Error handling                           */
  #include "H5MMprivate.h" /* Memory management                        */
  
  /****************/
  /* Local Macros */
  /****************/
  
  /* Max log message size */
  #define H5C_MAX_JSON_LOG_MSG_SIZE 1024
  
  /******************/
  /* Local Typedefs */
  /******************/
  
  /********************/
  /* Package Typedefs */
  /********************/
  
  typedef struct H5C_log_json_udata_t {
      FILE *outfile;
      char *message;
  } H5C_log_json_udata_t;
  
  /********************/
  /* Local Prototypes */
  /********************/
  
  /* Internal message handling calls */
  static herr_t H5C__json_write_log_message(H5C_log_json_udata_t *json_udata);
  
  /* Log message callbacks */
  static herr_t H5C__json_tear_down_logging(H5C_log_info_t *log_info);
  static herr_t H5C__json_write_start_log_msg(void *udata);
  static herr_t H5C__json_write_stop_log_msg(void *udata);
  static herr_t H5C__json_write_create_cache_log_msg(void *udata, herr_t fxn_ret_value);
  static herr_t H5C__json_write_destroy_cache_log_msg(void *udata);
  static herr_t H5C__json_write_evict_cache_log_msg(void *udata, herr_t fxn_ret_value);
  static herr_t H5C__json_write_expunge_entry_log_msg(void *udata, haddr_t address, int type_id,
                                                      herr_t fxn_ret_value);
  static herr_t H5C__json_write_flush_cache_log_msg(void *udata, herr_t fxn_ret_value);
  static herr_t H5C__json_write_insert_entry_log_msg(void *udata, haddr_t address, int type_id, unsigned flags,
                                                     size_t size, herr_t fxn_ret_value);
  static herr_t H5C__json_write_mark_entry_dirty_log_msg(void *udata, const H5C_cache_entry_t *entry,
                                                         herr_t fxn_ret_value);
  static herr_t H5C__json_write_mark_entry_clean_log_msg(void *udata, const H5C_cache_entry_t *entry,
                                                         herr_t fxn_ret_value);
  static herr_t H5C__json_write_mark_unserialized_entry_log_msg(void *udata, const H5C_cache_entry_t *entry,
                                                                herr_t fxn_ret_value);
  static herr_t H5C__json_write_mark_serialized_entry_log_msg(void *udata, const H5C_cache_entry_t *entry,
                                                              herr_t fxn_ret_value);
  static herr_t H5C__json_write_move_entry_log_msg(void *udata, haddr_t old_addr, haddr_t new_addr, int type_id,
                                                   herr_t fxn_ret_value);
  static herr_t H5C__json_write_pin_entry_log_msg(void *udata, const H5C_cache_entry_t *entry,
                                                  herr_t fxn_ret_value);
  static herr_t H5C__json_write_create_fd_log_msg(void *udata, const H5C_cache_entry_t *parent,
                                                  const H5C_cache_entry_t *child, herr_t fxn_ret_value);
  static herr_t H5C__json_write_protect_entry_log_msg(void *udata, const H5C_cache_entry_t *entry, int type_id,
                                                      unsigned flags, herr_t fxn_ret_value);
  static herr_t H5C__json_write_resize_entry_log_msg(void *udata, const H5C_cache_entry_t *entry,
                                                     size_t new_size, herr_t fxn_ret_value);
  static herr_t H5C__json_write_unpin_entry_log_msg(void *udata, const H5C_cache_entry_t *entry,
                                                    herr_t fxn_ret_value);
  static herr_t H5C__json_write_destroy_fd_log_msg(void *udata, const H5C_cache_entry_t *parent,
                                                   const H5C_cache_entry_t *child, herr_t fxn_ret_value);
  static herr_t H5C__json_write_unprotect_entry_log_msg(void *udata, haddr_t address, int type_id,
                                                        unsigned flags, herr_t fxn_ret_value);
  static herr_t H5C__json_write_set_cache_config_log_msg(void *udata, const H5AC_cache_config_t *config,
                                                         herr_t fxn_ret_value);
  static herr_t H5C__json_write_remove_entry_log_msg(void *udata, const H5C_cache_entry_t *entry,
                                                     herr_t fxn_ret_value);
  
  /*********************/
  /* Package Variables */
  /*********************/
  
  /*****************************/
  /* Library Private Variables */
  /*****************************/
  
  /*******************/
  /* Local Variables */
  /*******************/
  
  /* Note that there's no cache set up call since that's the
   * place where this struct is wired into the cache.
   */
  static H5C_log_class_t H5C_json_log_class_g = {"json",
                                                 H5C__json_tear_down_logging,
                                                 NULL, /* start logging */
                                                 NULL, /* stop logging */
                                                 H5C__json_write_start_log_msg,
                                                 H5C__json_write_stop_log_msg,
                                                 H5C__json_write_create_cache_log_msg,
                                                 H5C__json_write_destroy_cache_log_msg,
                                                 H5C__json_write_evict_cache_log_msg,
                                                 H5C__json_write_expunge_entry_log_msg,
                                                 H5C__json_write_flush_cache_log_msg,
                                                 H5C__json_write_insert_entry_log_msg,
                                                 H5C__json_write_mark_entry_dirty_log_msg,
                                                 H5C__json_write_mark_entry_clean_log_msg,
                                                 H5C__json_write_mark_unserialized_entry_log_msg,
                                                 H5C__json_write_mark_serialized_entry_log_msg,
                                                 H5C__json_write_move_entry_log_msg,
                                                 H5C__json_write_pin_entry_log_msg,
                                                 H5C__json_write_create_fd_log_msg,
                                                 H5C__json_write_protect_entry_log_msg,
                                                 H5C__json_write_resize_entry_log_msg,
                                                 H5C__json_write_unpin_entry_log_msg,
                                                 H5C__json_write_destroy_fd_log_msg,
                                                 H5C__json_write_unprotect_entry_log_msg,
                                                 H5C__json_write_set_cache_config_log_msg,
                                                 H5C__json_write_remove_entry_log_msg};
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_log_message
   *
   * Purpose:     Write a message to the log file and flush the file.
   *              The message string is neither modified nor freed.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_log_message(H5C_log_json_udata_t *json_udata)
  {
      size_t n_chars;
      herr_t ret_value = SUCCEED; /* Return value */
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->outfile);
      HDassert(json_udata->message);
  
      /* Write the log message and flush */
      n_chars = HDstrlen(json_udata->message);
      if ((int)n_chars != HDfprintf(json_udata->outfile, json_udata->message))
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "error writing log message")
      HDmemset((void *)(json_udata->message), 0, (size_t)(n_chars * sizeof(char)));
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_log_message() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C_log_json_set_up
   *
   * Purpose:     Setup for metadata cache logging.
   *
   *              Metadata logging is enabled and disabled at two levels. This
   *              function and the associated tear_down function open and close
   *              the log file. the start_ and stop_logging functions are then
   *              used to switch logging on/off. Optionally, logging can begin
   *              as soon as the log file is opened (set via the start_immediately
   *              parameter to this function).
   *
   *              The log functionality is split between the H5C and H5AC
   *              packages. Log state and direct log manipulation resides in
   *              H5C. Log messages are generated in H5AC and sent to
   *              the H5C__json_write_log_message function.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  herr_t
  H5C_log_json_set_up(H5C_log_info_t *log_info, const char log_location[], int mpi_rank)
  {
      H5C_log_json_udata_t *json_udata = NULL;
      char *                file_name  = NULL;
      size_t                n_chars;
      herr_t                ret_value = SUCCEED; /* Return value */
  
      FUNC_ENTER_NOAPI(FAIL)
  
      /* Sanity checks */
      HDassert(log_info);
      HDassert(log_location);
  
      /* Set up the class struct */
      log_info->cls = &H5C_json_log_class_g;
  
      /* Allocate memory for the JSON-specific data */
      if (NULL == (log_info->udata = H5MM_calloc(sizeof(H5C_log_json_udata_t))))
          HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed")
      json_udata = (H5C_log_json_udata_t *)(log_info->udata);
  
      /* Allocate memory for the message buffer */
      if (NULL == (json_udata->message = (char *)H5MM_calloc(H5C_MAX_JSON_LOG_MSG_SIZE * sizeof(char))))
          HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed")
  
      /* Possibly fix up the log file name.
       * The extra 39 characters are for adding the rank to the file name
       * under parallel HDF5. 39 characters allows > 2^127 processes which
       * should be enough for anybody.
       *
       * allocation size = "RANK_" + <rank # length> + dot + <path length> + \0
       */
      n_chars = 5 + 39 + 1 + HDstrlen(log_location) + 1;
      if (NULL == (file_name = (char *)H5MM_calloc(n_chars * sizeof(char))))
          HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL,
                      "can't allocate memory for mdc log file name manipulation")
  
      /* Add the rank to the log file name when MPI is in use */
      if (-1 == mpi_rank)
          HDsnprintf(file_name, n_chars, "%s", log_location);
      else
          HDsnprintf(file_name, n_chars, "RANK_%d.%s", mpi_rank, log_location);
  
      /* Open log file and set it to be unbuffered */
      if (NULL == (json_udata->outfile = HDfopen(file_name, "w")))
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "can't create mdc log file")
      HDsetbuf(json_udata->outfile, NULL);
  
  done:
      if (file_name)
          H5MM_xfree(file_name);
  
      /* Free and reset the log info struct on errors */
      if (FAIL == ret_value) {
          /* Free */
          if (json_udata && json_udata->message)
              H5MM_xfree(json_udata->message);
          if (json_udata)
              H5MM_xfree(json_udata);
  
          /* Reset */
          log_info->udata = NULL;
          log_info->cls   = NULL;
      }
  
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C_log_json_set_up() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_tear_down_logging
   *
   * Purpose:     Tear-down for metadata cache logging.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_tear_down_logging(H5C_log_info_t *log_info)
  {
      H5C_log_json_udata_t *json_udata = NULL;
      herr_t                ret_value  = SUCCEED; /* Return value */
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(log_info);
  
      /* Alias */
      json_udata = (H5C_log_json_udata_t *)(log_info->udata);
  
      /* Free the message buffer */
      H5MM_xfree(json_udata->message);
  
      /* Close log file */
      if (EOF == HDfclose(json_udata->outfile))
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "problem closing mdc log file")
      json_udata->outfile = NULL;
  
      /* Fre the udata */
      H5MM_xfree(json_udata);
  
      /* Reset the log class info and udata */
      log_info->cls   = NULL;
      log_info->udata = NULL;
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_tear_down_logging() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_start_log_msg
   *
   * Purpose:     Write a log message when logging starts.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_start_log_msg(void *udata)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED; /* Return value */
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
  
      /* Create the log message string (opens the JSON array) */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\n\
  \"HDF5 metadata cache log messages\" : [\n\
  {\
  \"timestamp\":%lld,\
  \"action\":\"logging start\"\
  },\n\
  ",
                 (long long)HDtime(NULL));
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_start_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_stop_log_msg
   *
   * Purpose:     Write a log message when logging ends.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_stop_log_msg(void *udata)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED; /* Return value */
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
  
      /* Create the log message string (closes the JSON array) */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"logging stop\"\
  }\n\
  ]}\n\
  ",
                 (long long)HDtime(NULL));
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_stop_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_create_cache_log_msg
   *
   * Purpose:     Write a log message for cache creation.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_create_cache_log_msg(void *udata, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED; /* Return value */
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"create\",\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_create_cache_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_destroy_cache_log_msg
   *
   * Purpose:     Write a log message for cache destruction.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_destroy_cache_log_msg(void *udata)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED; /* Return value */
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"destroy\"\
  },\n\
  ",
                 (long long)HDtime(NULL));
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_destroy_cache_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_evict_cache_log_msg
   *
   * Purpose:     Write a log message for eviction of cache entries.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_evict_cache_log_msg(void *udata, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"evict\",\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_evict_cache_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_expunge_entry_log_msg
   *
   * Purpose:     Write a log message for expunge of cache entries.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_expunge_entry_log_msg(void *udata, haddr_t address, int type_id, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"expunge\",\
  \"address\":0x%lx,\
  \"type_id\":%d,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)address, (int)type_id, (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_expunge_entry_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_flush_cache_log_msg
   *
   * Purpose:     Write a log message for cache flushes.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_flush_cache_log_msg(void *udata, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"flush\",\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_flush_cache_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_insert_entry_log_msg
   *
   * Purpose:     Write a log message for insertion of cache entries.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_insert_entry_log_msg(void *udata, haddr_t address, int type_id, unsigned flags, size_t size,
                                       herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"insert\",\
  \"address\":0x%lx,\
  \"type_id\":%d,\
  \"flags\":0x%x,\
  \"size\":%d,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)address, type_id, flags, (int)size,
                 (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_insert_entry_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_mark_entry_dirty_log_msg
   *
   * Purpose:     Write a log message for marking cache entries as dirty.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_mark_entry_dirty_log_msg(void *udata, const H5C_cache_entry_t *entry, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(entry);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"dirty\",\
  \"address\":0x%lx,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)entry->addr, (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_mark_entry_dirty_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_mark_entry_clean_log_msg
   *
   * Purpose:     Write a log message for marking cache entries as clean.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_mark_entry_clean_log_msg(void *udata, const H5C_cache_entry_t *entry, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED; /* Return value */
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(entry);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"clean\",\
  \"address\":0x%lx,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)entry->addr, (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_mark_entry_clean_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_mark_unserialized_entry_log_msg
   *
   * Purpose:     Write a log message for marking cache entries as unserialized.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_mark_unserialized_entry_log_msg(void *udata, const H5C_cache_entry_t *entry,
                                                  herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(entry);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"unserialized\",\
  \"address\":0x%lx,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)entry->addr, (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_mark_unserialized_entry_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_mark_serialize_entry_log_msg
   *
   * Purpose:     Write a log message for marking cache entries as serialize.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_mark_serialized_entry_log_msg(void *udata, const H5C_cache_entry_t *entry,
                                                herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED; /* Return value */
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(entry);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"serialized\",\
  \"address\":0x%lx,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)entry->addr, (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_mark_serialized_entry_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_move_entry_log_msg
   *
   * Purpose:     Write a log message for moving a cache entry.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_move_entry_log_msg(void *udata, haddr_t old_addr, haddr_t new_addr, int type_id,
                                     herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"move\",\
  \"old_address\":0x%lx,\
  \"new_address\":0x%lx,\
  \"type_id\":%d,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)old_addr, (unsigned long)new_addr, type_id,
                 (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_move_entry_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_pin_entry_log_msg
   *
   * Purpose:     Write a log message for pinning a cache entry.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_pin_entry_log_msg(void *udata, const H5C_cache_entry_t *entry, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(entry);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"pin\",\
  \"address\":0x%lx,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)entry->addr, (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_pin_entry_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_create_fd_log_msg
   *
   * Purpose:     Write a log message for creating a flush dependency between
   *              two cache entries.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_create_fd_log_msg(void *udata, const H5C_cache_entry_t *parent,
                                    const H5C_cache_entry_t *child, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(parent);
      HDassert(child);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"create_fd\",\
  \"parent_addr\":0x%lx,\
  \"child_addr\":0x%lx,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)parent->addr, (unsigned long)child->addr,
                 (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_create_fd_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_protect_entry_log_msg
   *
   * Purpose:     Write a log message for protecting a cache entry.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_protect_entry_log_msg(void *udata, const H5C_cache_entry_t *entry, int type_id,
                                        unsigned flags, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      char                  rw_s[16];
      herr_t                ret_value = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(entry);
  
      if (H5C__READ_ONLY_FLAG == flags)
          HDstrcpy(rw_s, "READ");
      else
          HDstrcpy(rw_s, "WRITE");
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"protect\",\
  \"address\":0x%lx,\
  \"type_id\":%d,\
  \"readwrite\":\"%s\",\
  \"size\":%d,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)entry->addr, type_id, rw_s, (int)entry->size,
                 (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_protect_entry_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_resize_entry_log_msg
   *
   * Purpose:     Write a log message for resizing a cache entry.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_resize_entry_log_msg(void *udata, const H5C_cache_entry_t *entry, size_t new_size,
                                       herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(entry);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"resize\",\
  \"address\":0x%lx,\
  \"new_size\":%d,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)entry->addr, (int)new_size, (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_resize_entry_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_unpin_entry_log_msg
   *
   * Purpose:     Write a log message for unpinning a cache entry.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_unpin_entry_log_msg(void *udata, const H5C_cache_entry_t *entry, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(entry);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"unpin\",\
  \"address\":0x%lx,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)entry->addr, (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_unpin_entry_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_destroy_fd_log_msg
   *
   * Purpose:     Write a log message for destroying a flush dependency
   *              between two cache entries.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_destroy_fd_log_msg(void *udata, const H5C_cache_entry_t *parent,
                                     const H5C_cache_entry_t *child, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(parent);
      HDassert(child);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"destroy_fd\",\
  \"parent_addr\":0x%lx,\
  \"child_addr\":0x%lx,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)parent->addr, (unsigned long)child->addr,
                 (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_destroy_fd_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_unprotect_entry_log_msg
   *
   * Purpose:     Write a log message for unprotecting a cache entry.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_unprotect_entry_log_msg(void *udata, haddr_t address, int type_id, unsigned flags,
                                          herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"unprotect\",\
  \"address\":0x%lx,\
  \"id\":%d,\
  \"flags\":%x,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)address, type_id, flags, (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_unprotect_entry_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_set_cache_config_log_msg
   *
   * Purpose:     Write a log message for setting the cache configuration.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_set_cache_config_log_msg(void *udata, const H5AC_cache_config_t H5_ATTR_NDEBUG_UNUSED *config,
                                           herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(config);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"set_config\",\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_set_cache_config_log_msg() */
  
  /*-------------------------------------------------------------------------
   * Function:    H5C__json_write_remove_entry_log_msg
   *
   * Purpose:     Write a log message for removing a cache entry.
   *
   * Return:      SUCCEED/FAIL
   *
   * Programmer:  Dana Robinson
   *              Fall 2018
   *
   *-------------------------------------------------------------------------
   */
  static herr_t
  H5C__json_write_remove_entry_log_msg(void *udata, const H5C_cache_entry_t *entry, herr_t fxn_ret_value)
  {
      H5C_log_json_udata_t *json_udata = (H5C_log_json_udata_t *)(udata);
      herr_t                ret_value  = SUCCEED;
  
      FUNC_ENTER_STATIC
  
      /* Sanity checks */
      HDassert(json_udata);
      HDassert(json_udata->message);
      HDassert(entry);
  
      /* Create the log message string */
      HDsnprintf(json_udata->message, H5C_MAX_JSON_LOG_MSG_SIZE, "\
  {\
  \"timestamp\":%lld,\
  \"action\":\"remove\",\
  \"address\":0x%lx,\
  \"returned\":%d\
  },\n\
  ",
                 (long long)HDtime(NULL), (unsigned long)entry->addr, (int)fxn_ret_value);
  
      /* Write the log message to the file */
      if (H5C__json_write_log_message(json_udata) < 0)
          HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
  
  done:
      FUNC_LEAVE_NOAPI(ret_value)
  } /* H5C__json_write_remove_entry_log_msg() */
  