|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
Please help with change of sample logger |
« View previous topic :: View next topic » |
Author |
Message
|
epox |
Posted: Mon Aug 21, 2006 6:58 am Post subject: Please help with change of sample logger |
|
|
Newbie
Joined: 21 Aug 2006 Posts: 2
|
Hi ,
We found a script that can log all messages from MQSeries to a file. This is exactly what we need, however we do not have the knowledge of modifying it, and we would like to include in this logfile the complete message. At this point, only the time and the size of the msg are logged.
Could anyone give us advice on how to modify it ? ( preferably modify it for us and compile into DLL but hints are good enough, we'll manage to modify it I hope )
It's a standard MQSeries demo C file. ( MSGMON.C )
The Code :
=======
/*---------------------------------------------------------------------------*/
/* */
/* Filename: MSGMON.C */
/* */
/* Description: */
/* This is a sample message exit function record all messages */
/* transmitted through a channel defined in MQSeries. */
/* A companion utility program called PUTMSGQ can be used to */
/* read the messages in the log file and writes them to a queue.*/
/* This function will work on any channels, e.g. send, receive, */
/* requester,etc. */
/* */
/* Please read the user documentation on how to set up this */
/* channel exit function under MQSeries. */
/* */
/* This function is used as Channel Message Exit Function under */
/* MQSeries. You must create this function as a library */
/* function under UNIX, or a DLL under NT for it to be */
/* functional. Please see user document for details on how to */
/* specify the Channel Message Exit function within MQSeries. */
/* This function opens an INI file, which can be specified in */
/* Channel Message Exit Data in the channel definition, see */
/* user document. This function uses CHANNEL.INI under \tmp */
/* directory as default if no INI is specified in Channel */
/* Message Exit Data. The key values the function looks for in */
/* the INI file are Channel Log Filename and Message Buffer */
/* filename, please see CHANNEL.INI for setup. This function */
/* logs all channel activities into the Channel Log file. */
/* Messages passing through the channel will be written into */
/* the Message Buffer file. */
/* */
/* Statement: Licensed Materials - Property of IBM */
/* Copyright IBM Corp. 1997 */
/* All rights reserved. */
/* */
/* U.S. Government Users Restricted Rights -*/
/* use, duplication or disclosure restricted*/
/* by GSA ADP Schedule Contract with IBM */
/* Corp. */
/* */
/* Modification History: */
/* Date Who Version Description of change */
/* ---------- --------------- --------- ------------------------- */
/* 03/20/1997 Chak Pang 1.0 changed "[" to "??(" and "]" */
/* to "??)". Also added comments */
/* suggested by Jeff Hooper and */
/* Harry Halliwell from Hursley, */
/* U.K. */
/* */
/* 04/03/1997 Chak Pang 1.0 Tidied up comments. */
/* */
/* 04/28/1997 Chak Pang 1.1 Changed "fopen( INI_FILENAME" */
/* to "fopen( fn" in getINI() */
/* So it won't open the default */
/* INI file everytime. */
/* Authors: Tom McCann */
/* IBM Global Services */
/* Cincinnati, Ohio, USA */
/* Phone: 513-762-2060 */
/* */
/* Chak Pang */
/* IBM Global Services */
/* Columbus, Ohio, USA */
/* Phone: 614-225-3663 */
/* */
/* Dependencies: channel.h */
/* */
/* Restrictions: The INI filename must be less than 128 characters */
/* */
/* Disclaimer: this program has been tested under AIX and NT to the */
/* authors' satisfaction. You may use this program at your own */
/* risk. IBM and the authors are not responsible for any */
/* unexpected results generated by this program. */
/* */
/*---------------------------------------------------------------------------*/
/* standard headers */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <locale.h>
#ifdef AIX
#include <langinfo.h>
#endif
#include <sys/types.h>
#include <sys/timeb.h>
#include <time.h>
/* MQSeries headers */
#include <cmqc.h>
#include <cmqxc.h>
#include "channel.h"
char timebuf??(130??);
char Channel_Logfile??(129??);
char MsgBufFile??(129??);
char ini_filename??(129??);
FILE * OST = 0;
/* define output file and statement prototype */
#define DBGPRINTF(x) { \
OST=fopen(Channel_Logfile,"a+"); \
if(OST) fprintf x; \
fclose(OST); \
}
void writer (long *, char *); /* prototype for file writer function */
void getINI( void );
/* dummy function used as entry point to exit, only needed for AIX boxes */
void MQENTRY MQStart(void) {;}
void MQENTRY MsgExit( PMQCXP pChannelExitParams,
PMQCD pChannelDefinition,
PMQLONG pDataLength,
PMQLONG pAgentBufferLength,
PMQBYTE AgentBuffer,
PMQLONG pExitBufferLength,
PMQPTR pExitBufferAddr)
{
short i;
struct timeb t;
char millisec??(25??);
/*** Get time string to use in all messages ***/
time_t clock = time( (time_t*) NULL);
struct tm *tmptr = localtime(&clock);
strcpy(timebuf, asctime(tmptr));
ftime( &t );
memset( millisec, 0, sizeof( millisec ) );
sprintf( millisec, " Time:%ld.%d", t.time, t.millitm );
strcat( timebuf, millisec );
if ( strlen(pChannelExitParams->ExitData) )
{
memset( ini_filename, 0, sizeof( ini_filename ) );
strncpy( ini_filename, pChannelExitParams->ExitData, MQ_EXIT_DATA_LENGTH );
/*------------------------*/
/* remove space from data */
/*------------------------*/
for ( i = MQ_EXIT_DATA_LENGTH - 1; i > 0; i-- )
{
if ( ini_filename??(i??) != ' ' && ini_filename??(i??) )
break;
ini_filename??(i??) = 0;
}
}
getINI();
/*** Check call type - initialization, message, or exit ***/
/* */
switch( pChannelExitParams-> ExitReason )
{
case MQXR_INIT:
DBGPRINTF((OST,"\nChannel message exit called at MCA initialization %s",timebuf));
break;
case MQXR_MSG:
/*** Call subroutine to write record to output file ***/
/* */
writer (pDataLength, (char *)AgentBuffer);
DBGPRINTF((OST,"\nMessage written, length = %li %s \n",*pDataLength, timebuf));
break;
case MQXR_TERM:
DBGPRINTF((OST, "\nMessage channel exit called at MCA termination %s\n",timebuf));
break;
default:
DBGPRINTF((OST,"\nMessage channel exit called with invalid reason code: %d %s", pChannelExitParams-> ExitReason, timebuf));
break;
} /* switch */
/*** Set exit response = OK in all circumstances ***/
pChannelExitParams -> ExitResponse = MQXCC_OK;
return;
}/* end exit */
/*------------------------------------------------------------------
write() - writes a MQSeries message to a log file.
-------------------------------------------------------------------*/
void writer(long *lngth, char *bf)
{
long msgsize;
int n;
FILE *fp;
getINI();
fp = fopen(MsgBufFile, "ab");
if (fp == NULL)
{
printf("Error opening <%s> to write message. Error #: %d", MsgBufFile, errno );
return;
}
msgsize = *lngth;
n = fwrite(&msgsize, sizeof(msgsize), 1, fp); /* put record length */
n = fwrite(bf, msgsize, 1, fp); /* and message buffer */
fclose(fp);
} /* end writer */
/*---------------------------------------------------------
getINI() - read information from INI file
-----------------------------------------------------------*/
void getINI( void )
{
FILE *ini_fp;
char *ptr, *name_ptr;
char field_val??(129??), Ini_s??(129??), fn??(129??);
short len;
memset( Ini_s, 0, sizeof( Ini_s ) );
memset( field_val, 0, sizeof( field_val ) );
memset( MsgBufFile, 0, sizeof ( MsgBufFile ) );
memset( Channel_Logfile, 0, sizeof( Channel_Logfile ) );
if ( strlen( ini_filename ) ) /* if Channel Exit defined INI filename */
strcpy( fn, ini_filename ); /* use it */
else /* otherwise use default INI filename */
strcpy( fn, INI_FILENAME );
if ( (ini_fp = fopen( fn, "r" )) == NULL )
{
fprintf(stderr, "\nUnable to open %s. Error #: %d", fn, errno );
return;
}
/*-----------------------------*/
/* read the INI file until eof */
/*-----------------------------*/
while ( (ptr = fgets( Ini_s, sizeof(Ini_s) - 1, ini_fp )) != NULL )
{
len = strlen( Ini_s );
if ( Ini_s??(len -1??) == LINEFEED )
Ini_s??(len-1??) = 0; /* null out '\n' */
if ( (name_ptr = strchr( Ini_s, EQUAL )) == NULL ) /* no '=' found */
continue;
ptr = name_ptr + 1;
*name_ptr = 0; /* set null for s[] */
strcpy( field_val, ptr );
/*---------------------------------------------------*/
/* remove comments and unwanted characters from data */
/*---------------------------------------------------*/
while ( *ptr )
{
if ( *ptr == ' ' ) /* stop at first space */
{
*ptr = 0;
break;
}
ptr++;
}
if ( !strcmp( MESSAGE_BUFFER_FILE, Ini_s ) ) /* look for message buffer filename */
{
strcpy( MsgBufFile, field_val );
}
else
{
if ( !strcmp( CHANNEL_LOGFILE, Ini_s ) )
{
strcpy( Channel_Logfile, field_val );
}
}
memset( Ini_s, 0, sizeof( Ini_s ) );
memset( field_val, 0, sizeof( field_val ) );
}
fclose( ini_fp );
return;
}
======= |
|
Back to top |
|
 |
Vitor |
Posted: Mon Aug 21, 2006 7:06 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
Exits are described in the Application Programming Guide & Reference. How to define an exit to MQ is described in the Command Reference. You'll find them (as well as the rest of the documentation) at:
http://publib.boulder.ibm.com/infocenter/wmqv6/v6r0/index.jsp
Adding new logged items should not be beyond the competence of a C programmer, but be warned - exits are an advanced MQ topic. Incorrectly coded ones can cause all sorts of bad things to happen!  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
jefflowrey |
Posted: Mon Aug 21, 2006 7:14 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
You may instead want to implement a different sample exit unchanged - mirrorq - and then write a standard MQ program to write the messages to a file.
But you should really really really think about this.
For one, a file is probably not where you want to write these messages. Files are clunky to maintain and clunkier to search and edit. Files are also hard to make visible to the enterprise, and hard to provide good security auditing on.
For two, you need to really understand the retention requirements of this file.
For three - you're adding a performance impact to your system on every MQ put call. You need to characterize (test) this impact, and check it against business requirements and SLAs. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
epox |
Posted: Mon Aug 21, 2006 8:39 am Post subject: |
|
|
Newbie
Joined: 21 Aug 2006 Posts: 2
|
thanks for the replies guys :
My next question is : Does either of you ( or anyone else with knowledge of the API ) want to program this for us ( like you say it's a small change ) and what would it $$ ?
Thanks! |
|
Back to top |
|
 |
Vitor |
Posted: Tue Aug 22, 2006 1:01 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
It may be a small change, but it's potentially a world of hurt for the reasons jefflowrey correctly points out. I don't have time to get involved at the moment; for some reason I'm expected to actually do what I'm paid to as well as post here!
Weird yet true.  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
|
|
 |
|
Page 1 of 1 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
|
|