diff --git a/c/zss.c b/c/zss.c index 428d0217e..b2b1d527d 100644 --- a/c/zss.c +++ b/c/zss.c @@ -775,6 +775,7 @@ void checkAndSetVariableWithEnvOverride(JsonObject *mvdSettings, } static void initLoggingComponents(void) { + logConfigureDestination3(NULL,LOG_DEST_PRINTF_STDOUT,"printf(stdout)",NULL,printStdout,NULL,zssFormatter); logConfigureComponent(NULL, LOG_COMP_ID_SECURITY, "ZSS Security API", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO); logConfigureComponent(NULL, LOG_COMP_DISCOVERY, "Zowe Discovery", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO); logConfigureComponent(NULL, LOG_COMP_RESTDATASET, "Zowe Dataset REST", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO); @@ -783,7 +784,7 @@ static void initLoggingComponents(void) { logConfigureComponent(NULL, LOG_COMP_DATASERVICE, "ZSS dataservices", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO); logConfigureComponent(NULL, LOG_COMP_ID_MVD_SERVER, "ZSS server", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO); logConfigureComponent(NULL, LOG_COMP_ID_CTDS, "CT/DS", LOG_DEST_PRINTF_STDOUT, ZOWE_LOG_INFO); - zowelog(NULL, LOG_COMP_ID_MVD_SERVER, ZOWE_LOG_INFO, ZSS_LOG_ZSS_START_VER_MSG, productVersion); + zowelogx(NULL, LOG_COMP_ID_MVD_SERVER, ZOWE_LOG_INFO, ZSS_LOG_ZSS_START_VER_MSG, productVersion); } static void initVersionComponents(void){ diff --git a/c/zssLogging.c b/c/zssLogging.c index bcc88aee5..5e593f6b3 100644 --- a/c/zssLogging.c +++ b/c/zssLogging.c @@ -33,6 +33,12 @@ #include "zowetypes.h" #include "logging.h" +#include "zssLogging.h" +#include "timeutls.h" +#include "zos.h" +#include "openprims.h" +#include "sys/time.h" +#include "time.h" bool isLogLevelValid(int level) { @@ -43,6 +49,173 @@ bool isLogLevelValid(int level) { return TRUE; } +static void getLocationData(char *path, int line, char **locationInfo, uint64 compID, LoggingComponent *component) { + + char prefix[PREFIX_SUFFIX_SIZE]; + char suffix[PREFIX_SUFFIX_SIZE]; + + unsigned int id = compID & 0xFFFFFFFF; + if(compID >= LOG_PROD_COMMON && compID < LOG_PROD_ZIS) { + memcpy(prefix, LOG_PREFIX_ZCC, sizeof(LOG_PREFIX_ZCC)); + switch (id) { // most of these don't actally log, but are defined in logging.h + case LOG_COMP_ALLOC: + memcpy(suffix, LOG_COMP_TEXT_ALLOC, sizeof(LOG_COMP_TEXT_ALLOC)); + break; + case LOG_COMP_UTILS: + memcpy(suffix, LOG_COMP_TEXT_UTILS, sizeof(LOG_COMP_TEXT_UTILS)); + break; + case LOG_COMP_COLLECTIONS: + memcpy(suffix, LOG_COMP_TEXT_COLLECTIONS, sizeof(LOG_COMP_TEXT_COLLECTIONS)); + break; + case LOG_COMP_SERIALIZATION: + memcpy(suffix, LOG_COMP_TEXT_SERIALIZATION, sizeof(LOG_COMP_TEXT_SERIALIZATION)); + break; + case LOG_COMP_ZLPARSER: + memcpy(suffix, LOG_COMP_TEXT_ZLPARSER, sizeof(LOG_COMP_TEXT_ZLPARSER)); + break; + case LOG_COMP_ZLCOMPILER: + memcpy(suffix, LOG_COMP_TEXT_ZLCOMPILER, sizeof(LOG_COMP_TEXT_ZLCOMPILER)); + break; + case LOG_COMP_ZLRUNTIME: + memcpy(suffix, LOG_COMP_TEXT_ZLRUNTIME, sizeof(LOG_COMP_TEXT_ZLRUNTIME)); + break; + case LOG_COMP_STCBASE: + memcpy(suffix, LOG_COMP_TEXT_STCBASE, sizeof(LOG_COMP_TEXT_STCBASE)); + break; + case LOG_COMP_HTTPSERVER: + memcpy(suffix, LOG_COMP_TEXT_HTTPSERVER, sizeof(LOG_COMP_TEXT_HTTPSERVER)); + break; + case LOG_COMP_DISCOVERY: + memcpy(suffix, LOG_COMP_TEXT_DISCOVERY, sizeof(LOG_COMP_TEXT_DISCOVERY)); + break; + case LOG_COMP_DATASERVICE: + memcpy(suffix, LOG_COMP_TEXT_DATASERVICE, sizeof(LOG_COMP_TEXT_DATASERVICE)); + break; + case LOG_COMP_CMS: + memcpy(suffix, LOG_COMP_TEXT_CMS, sizeof(LOG_COMP_TEXT_CMS)); + break; + case LOG_COMP_LPA: + memcpy(suffix, LOG_COMP_TEXT_LPA, sizeof(LOG_COMP_TEXT_LPA)); + break; + case LOG_COMP_RESTDATASET: + memcpy(suffix, LOG_COMP_TEXT_RESTDATASET, sizeof(LOG_COMP_TEXT_RESTDATASET)); + break; + case LOG_COMP_RESTFILE: + memcpy(suffix, LOG_COMP_TEXT_RESTFILE, sizeof(LOG_COMP_TEXT_RESTFILE)); + break; + } + } else if (compID >= LOG_PROD_ZIS && compID < LOG_PROD_ZSS) { + memcpy(prefix, LOG_PREFIX_ZIS, sizeof(LOG_PREFIX_ZIS)); + } else if (compID >= LOG_PROD_ZSS && compID < LOG_PROD_PLUGINS ) { + memcpy(prefix, LOG_PREFIX_ZSS, sizeof(LOG_PREFIX_ZSS)); + switch (id) { + case LOG_COMP_ID_ZSS: + memcpy(suffix, LOG_COMP_ID_TEXT_ZSS, sizeof(LOG_COMP_ID_TEXT_ZSS)); + break; + case LOG_COMP_ID_CTDS: + memcpy(suffix, LOG_COMP_ID_TEXT_CTDS, sizeof(LOG_COMP_ID_TEXT_CTDS)); + break; + case LOG_COMP_ID_SECURITY: + memcpy(suffix, LOG_COMP_ID_TEXT_SECURITY, sizeof(LOG_COMP_ID_TEXT_SECURITY)); + break; + case LOG_COMP_ID_UNIXFILE: + memcpy(suffix, LOG_COMP_ID_TEXT_UNIXFILE, sizeof(LOG_COMP_ID_TEXT_UNIXFILE)); + break; + } + } else { + //Do nothing? Leave Prefix/Suffix blank? or fill Suffix with component->name if exists? + } + + char *filename; + if (strrchr(path, '/') != NULL) { + filename = strrchr(path, '/'); // returns a pointer to the last occurence of '/' + filename+=1; + } else if (path != NULL) { + filename = path; + } else { + //What should happen if path is null? + } + // formatting + prefix + suffix + filename + line number + int locationSize = LOCATION_PREFIX_PADDING + strlen(prefix) + strlen(suffix) + strlen(filename) + LOCATION_SUFFIX_PADDING; + *locationInfo = (char*) safeMalloc(locationSize, "locationInfo"); + snprintf(*locationInfo, locationSize, "(%s:%s,%s:%d)", prefix, suffix, filename, line); +} + +static void initZssLogMessagePrefix(LogMessagePrefix *prefix, LoggingComponent *component, char* path, int line, int level, uint64 compID) { + ASCB *ascb = getASCB(); + char *jobName = getASCBJobname(ascb); + + ACEE *acee; + acee = getAddressSpaceAcee(); + char user[USER_SIZE] = { 0 }; + snprintf(user,sizeof(user), acee->aceeuser+1); + pthread_t threadID = pthread_self(); + char thread[THREAD_SIZE]; + snprintf(thread,sizeof(thread), "%d", threadID); + char logLevel[LOG_LEVEL_MAX_SIZE]; + + switch(level) { + case LOG_LEVEL_ID_SEVERE: + memcpy(logLevel, LOG_LEVEL_SEVERE, sizeof(LOG_LEVEL_SEVERE)); + break; + case LOG_LEVEL_ID_WARN: + memcpy(logLevel, LOG_LEVEL_WARN, sizeof(LOG_LEVEL_WARN)); + break; + case LOG_LEVEL_ID_INFO: + memcpy(logLevel, LOG_LEVEL_INFO, sizeof(LOG_LEVEL_INFO)); + break; + case LOG_LEVEL_ID_DEBUG: + memcpy(logLevel, LOG_LEVEL_DEBUG, sizeof(LOG_LEVEL_DEBUG)); + break; + case LOG_LEVEL_ID_DEBUG2: + memcpy(logLevel, LOG_LEVEL_DEBUG, sizeof(LOG_LEVEL_DEBUG)); + break; + case LOG_LEVEL_ID_TRACE: + memcpy(logLevel, LOG_LEVEL_TRACE, sizeof(LOG_LEVEL_TRACE)); + break; + } + + char *locationInfo; // largest possible variation in size + getLocationData(path, line, &locationInfo, compID, component); // location info is allocated in getLocationData + struct timeval tv; + struct tm tm; + gettimeofday(&tv, NULL); + localtime_r(&tv.tv_sec, &tm); + static const size_t ISO8601_LEN = 30; + char datetime[ISO8601_LEN]; + char timestamp[ISO8601_LEN]; // ISO-8601 timestamp + strftime(datetime, sizeof datetime, "%Y-%m-%d %H:%M:%S", &tm); + snprintf(timestamp, sizeof timestamp, "%s.%d", datetime, tv.tv_usec); + snprintf(prefix->text, sizeof(prefix->text), "%22.22s <%8.8s:%s> %s %s %s ", timestamp, jobName, thread, user, logLevel, locationInfo); + free(locationInfo); +} + + +void zssFormatter(LoggingContext *context, LoggingComponent *component, void *data, int level, uint64 compID, void *userData, char *formatString, va_list argList) { + char messageBuffer[PREFIXED_LINE_MAX_MSG_LENGTH]; + size_t messageLength = vsnprintf(messageBuffer, sizeof(messageBuffer), formatString, argList); + if (messageLength > sizeof(messageBuffer) - 1) { + messageLength = sizeof(messageBuffer) - 1; + } + fileAndLine *test = (struct fileAndLine_tag*)userData; + LogMessagePrefix prefix = {0}; + char *nextLine = messageBuffer; + char *lastLine = messageBuffer + messageLength; + for (int lineIdx = 0; lineIdx < PREFIXED_LINE_MAX_COUNT; lineIdx++) { + if (nextLine >= lastLine) { + break; + } + char *endOfLine = strchr(nextLine, '\n'); + size_t nextLineLength = endOfLine ? (endOfLine - nextLine) : (lastLine - nextLine); + memset(prefix.text, ' ', sizeof(prefix.text)); + if (lineIdx == 0) { + initZssLogMessagePrefix(&prefix, component, test->fileName, test->lineNnumber, level, compID); + } + printf("%.*s%.*s\n", sizeof(prefix.text), prefix.text, nextLineLength, nextLine); + nextLine += (nextLineLength + 1); + } +} + /* This program and the accompanying materials are diff --git a/deps/zowe-common-c b/deps/zowe-common-c index 911d651ed..8df41b047 160000 --- a/deps/zowe-common-c +++ b/deps/zowe-common-c @@ -1 +1 @@ -Subproject commit 911d651ed2f3c1f7c348898958df76d7de942c90 +Subproject commit 8df41b047e8d78a2f06179722639f04440cbe544 diff --git a/h/zssLogging.h b/h/zssLogging.h index 74675318e..f229c859e 100644 --- a/h/zssLogging.h +++ b/h/zssLogging.h @@ -38,9 +38,72 @@ #define LOG_COMP_ID_SECURITY 0x008F000300030000 #define LOG_COMP_ID_UNIXFILE 0x008F000300040000 #define LOG_COMP_ID_DATASERVICE 0x008F000300050000 +#define LOG_COMP_ID_ZSS 0x008F000300060000 + +#define LOG_COMP_TEXT_ALLOC "alloc" +#define LOG_COMP_TEXT_UTILS "utils" +#define LOG_COMP_TEXT_COLLECTIONS "collections" +#define LOG_COMP_TEXT_SERIALIZATION "serialization" +#define LOG_COMP_TEXT_ZLPARSER "zlparser" +#define LOG_COMP_TEXT_ZLCOMPILER "zlcompiler" +#define LOG_COMP_TEXT_ZLRUNTIME "zlruntime" +#define LOG_COMP_TEXT_STCBASE "stcbase" +#define LOG_COMP_TEXT_HTTPSERVER "httpserver" +#define LOG_COMP_TEXT_DISCOVERY "discovery" +#define LOG_COMP_TEXT_DATASERVICE "dataservice" +#define LOG_COMP_TEXT_CMS "cms" +#define LOG_COMP_TEXT_LPA "lpa" +#define LOG_COMP_TEXT_RESTDATASET "restdataset" +#define LOG_COMP_TEXT_RESTFILE "restfile" + +#define LOG_COMP_ID_TEXT_ZSS "zss" +#define LOG_COMP_ID_TEXT_CTDS "ctds" +#define LOG_COMP_ID_TEXT_SECURITY "security" +#define LOG_COMP_ID_TEXT_UNIXFILE "unixfile" + +#define LOG_PREFIX_ZCC "_zcc" +#define LOG_PREFIX_ZIS "_zis" +#define LOG_PREFIX_ZSS "_zss" + +#define LOG_LEVEL_SEVERE "SEVERE" +#define LOG_LEVEL_WARN "WARN" +#define LOG_LEVEL_INFO "INFO" +#define LOG_LEVEL_DEBUG "DEBUG" +#define LOG_LEVEL_TRACE "TRACE" + +#define LOG_LEVEL_ID_SEVERE 0 +#define LOG_LEVEL_ID_WARN 1 +#define LOG_LEVEL_ID_INFO 2 +#define LOG_LEVEL_ID_DEBUG 3 +#define LOG_LEVEL_ID_DEBUG2 4 +#define LOG_LEVEL_ID_TRACE 5 + +#define PREFIXED_LINE_MAX_COUNT 1000 +#define PREFIXED_LINE_MAX_MSG_LENGTH 4096 +#define LOG_MSG_PREFIX_SIZE 1000 +#define LOCATION_PREFIX_PADDING 7 +#define LOCATION_SUFFIX_PADDING 5 +#define USER_SIZE 7 //Will this always be 7? +#define THREAD_SIZE 10 +#define LOG_LEVEL_MAX_SIZE 16 +#define PREFIX_SUFFIX_SIZE 128 + +#define LOG_DEFAULT_COMPONENT_COUNT 128 +#define LOG_VENDOR_HT_BACKBONE_SIZE 127 + +typedef struct LogMessagePrefix_tag { + char text[LOG_MSG_PREFIX_SIZE]; +} LogMessagePrefix; + +typedef struct fileAndLine_tag{ + char *fileName; + int lineNnumber; +} fileAndLine; bool isLogLevelValid(int level); - +extern LoggingContext *zoweLoggingContext; +LoggingContext *getZoweLoggingContext(); +void zssFormatter(LoggingContext *context, LoggingComponent *component, void *data, int level, uint64 compID, void *userData, char *formatString, va_list argList); /* default message IDs */ /* 0000 - 0999 are messages reserved for for crossmemory (see crossmemory.h) */