log_messages.c revision 2362
609N/A/*
609N/A * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
609N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
609N/A *
609N/A * This code is free software; you can redistribute it and/or modify it
609N/A * under the terms of the GNU General Public License version 2 only, as
609N/A * published by the Free Software Foundation. Oracle designates this
609N/A * particular file as subject to the "Classpath" exception as provided
609N/A * by Oracle in the LICENSE file that accompanied this code.
609N/A *
609N/A * This code is distributed in the hope that it will be useful, but WITHOUT
609N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
609N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
609N/A * version 2 for more details (a copy is included in the LICENSE file that
609N/A * accompanied this code).
609N/A *
609N/A * You should have received a copy of the GNU General Public License version
609N/A * 2 along with this work; if not, write to the Free Software Foundation,
609N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
609N/A *
609N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
609N/A * or visit www.oracle.com if you need additional information or have any
609N/A * questions.
609N/A */
609N/A
609N/A#include "util.h"
609N/A
609N/A#include <time.h>
609N/A#include <errno.h>
609N/A#include <sys/types.h>
609N/A
609N/A#include "proc_md.h"
609N/A
609N/A#include "log_messages.h"
609N/A
609N/A#ifdef JDWP_LOGGING
609N/A
609N/A#define MAXLEN_INTEGER 20
609N/A#define MAXLEN_FILENAME 256
609N/A#define MAXLEN_TIMESTAMP 80
609N/A#define MAXLEN_LOCATION (MAXLEN_FILENAME+MAXLEN_INTEGER+16)
609N/A#define MAXLEN_MESSAGE 256
609N/A#define MAXLEN_EXEC (MAXLEN_FILENAME*2+MAXLEN_INTEGER+16)
609N/A
609N/Astatic MUTEX_T my_mutex = MUTEX_INIT;
609N/A
609N/A/* Static variables (should be protected with mutex) */
609N/Astatic int logging;
609N/Astatic FILE * log_file;
609N/Astatic char logging_filename[MAXLEN_FILENAME+1+6];
609N/Astatic char location_stamp[MAXLEN_LOCATION+1];
609N/Astatic PID_T processPid;
609N/Astatic int open_count;
609N/A
794N/A/* Ascii id of current native thread. */
609N/Astatic void
609N/Aget_time_stamp(char *tbuf, size_t ltbuf)
609N/A{
609N/A char format[MAXLEN_TIMESTAMP+1];
609N/A unsigned millisecs = 0;
609N/A time_t t = 0;
609N/A
609N/A GETMILLSECS(millisecs);
609N/A if ( time(&t) == (time_t)(-1) )
609N/A t = 0;
609N/A (void)strftime(format, sizeof(format),
609N/A /* Break this string up for SCCS's sake */
609N/A "%" "d.%" "m.%" "Y %" "T.%%.3d %" "Z", localtime(&t));
609N/A (void)snprintf(tbuf, ltbuf, format, (int)(millisecs));
609N/A}
609N/A
609N/A/* Get basename of filename */
609N/Astatic const char *
609N/Afile_basename(const char *file)
609N/A{
609N/A char *p1;
609N/A char *p2;
609N/A
609N/A if ( file==NULL )
609N/A return "unknown";
609N/A p1 = strrchr(file, '\\');
609N/A p2 = strrchr(file, '/');
609N/A p1 = ((p1 > p2) ? p1 : p2);
609N/A if (p1 != NULL) {
609N/A file = p1 + 1;
609N/A }
609N/A return file;
609N/A}
609N/A
609N/A/* Fill in the exact source location of the LOG entry. */
609N/Astatic void
609N/Afill_location_stamp(const char *flavor, const char *file, int line)
609N/A{
609N/A (void)snprintf(location_stamp, sizeof(location_stamp),
609N/A "%s:\"%s\":%d;",
609N/A flavor, file_basename(file), line);
609N/A location_stamp[sizeof(location_stamp)-1] = 0;
609N/A}
609N/A
609N/A/* Begin a log entry. */
609N/Avoid
609N/Alog_message_begin(const char *flavor, const char *file, int line)
609N/A{
609N/A MUTEX_LOCK(my_mutex); /* Unlocked in log_message_end() */
609N/A if ( logging ) {
609N/A location_stamp[0] = 0;
609N/A fill_location_stamp(flavor, file, line);
609N/A }
609N/A}
609N/A
609N/A/* Standard Logging Format Entry */
609N/Astatic void
609N/Astandard_logging_format(FILE *fp,
609N/A const char *datetime,
609N/A const char *level,
609N/A const char *product,
609N/A const char *module,
609N/A const char *optional,
609N/A const char *messageID,
609N/A const char *message)
609N/A{
609N/A const char *format;
609N/A
609N/A /* "[#|Date&Time&Zone|LogLevel|ProductName|ModuleID|
609N/A * OptionalKey1=Value1;OptionalKeyN=ValueN|MessageID:MessageText|#]\n"
609N/A */
609N/A
609N/A format="[#|%s|%s|%s|%s|%s|%s:%s|#]\n";
609N/A
609N/A print_message(fp, "", "", format,
609N/A datetime,
609N/A level,
609N/A product,
609N/A module,
609N/A optional,
609N/A messageID,
609N/A message);
609N/A}
609N/A
609N/A/* End a log entry */
609N/Avoid
609N/Alog_message_end(const char *format, ...)
609N/A{
609N/A if ( logging ) {
609N/A va_list ap;
609N/A THREAD_T tid;
609N/A char datetime[MAXLEN_TIMESTAMP+1];
609N/A const char *level;
609N/A const char *product;
609N/A const char *module;
609N/A char optional[MAXLEN_INTEGER+6+MAXLEN_INTEGER+6+MAXLEN_LOCATION+1];
609N/A const char *messageID;
609N/A char message[MAXLEN_MESSAGE+1];
609N/A
609N/A /* Grab the location, start file if needed, and clear the lock */
609N/A if ( log_file == NULL && open_count == 0 && logging_filename[0] != 0 ) {
609N/A open_count++;
609N/A log_file = fopen(logging_filename, "w");
609N/A if ( log_file!=NULL ) {
609N/A (void)setvbuf(log_file, NULL, _IOLBF, BUFSIZ);
609N/A } else {
609N/A logging = 0;
609N/A }
609N/A }
609N/A
609N/A if ( log_file != NULL ) {
609N/A
609N/A /* Get the rest of the needed information */
794N/A tid = GET_THREAD_ID();
609N/A level = "FINEST"; /* FIXUP? */
609N/A product = "J2SE1.5"; /* FIXUP? */
609N/A module = "jdwp"; /* FIXUP? */
609N/A messageID = ""; /* FIXUP: Unique message string ID? */
609N/A (void)snprintf(optional, sizeof(optional),
794N/A "LOC=%s;PID=%d;THR=t@%d",
794N/A location_stamp,
794N/A (int)processPid,
794N/A (int)tid);
794N/A
609N/A /* Construct message string. */
609N/A va_start(ap, format);
609N/A (void)vsnprintf(message, sizeof(message), format, ap);
609N/A va_end(ap);
609N/A
609N/A get_time_stamp(datetime, sizeof(datetime));
609N/A
609N/A /* Send out standard logging format message */
794N/A standard_logging_format(log_file,
794N/A datetime,
609N/A level,
609N/A product,
609N/A module,
609N/A optional,
609N/A messageID,
609N/A message);
609N/A }
609N/A location_stamp[0] = 0;
609N/A }
609N/A MUTEX_UNLOCK(my_mutex); /* Locked in log_message_begin() */
609N/A}
609N/A
609N/A#endif
609N/A
609N/A/* Set up the logging with the name of a logging file. */
609N/Avoid
609N/Asetup_logging(const char *filename, unsigned flags)
609N/A{
609N/A#ifdef JDWP_LOGGING
609N/A FILE *fp = NULL;
609N/A
609N/A /* Turn off logging */
609N/A logging = 0;
609N/A gdata->log_flags = 0;
609N/A
609N/A /* Just return if not doing logging */
609N/A if ( filename==NULL || flags==0 )
609N/A return;
609N/A
609N/A /* Create potential filename for logging */
609N/A processPid = GETPID();
609N/A (void)snprintf(logging_filename, sizeof(logging_filename),
609N/A "%s.%d", filename, (int)processPid);
609N/A
609N/A /* Turn on logging (do this last) */
609N/A logging = 1;
609N/A gdata->log_flags = flags;
609N/A
609N/A#endif
609N/A}
609N/A
609N/A/* Finish up logging, flush output to the logfile. */
609N/Avoid
609N/Afinish_logging(int exit_code)
609N/A{
609N/A#ifdef JDWP_LOGGING
609N/A MUTEX_LOCK(my_mutex);
609N/A if ( logging ) {
609N/A logging = 0;
609N/A if ( log_file != NULL ) {
609N/A (void)fflush(log_file);
609N/A (void)fclose(log_file);
609N/A log_file = NULL;
609N/A }
609N/A }
609N/A MUTEX_UNLOCK(my_mutex);
609N/A#endif
609N/A}
609N/A