char *fmt, ...);
/**
+ * Formats a logging message and stores it to local file to be delivered by IL
+ * (which is also notified through UNIX socket)
+ * \brief generic synchronous logging function
+ * \param[in,out] context context to work with,
+ * \param[in] event type of the event,
+ * \param[in] fmt printf()-like format string,
+ * \param[in] ... event specific values/data according to fmt,
+ * \retval 0 successful completition,
+ * \retval EINVAL bad jobId, unknown event code, or the format string together with the remaining arguments does not form a valid event,
+ * \retval ENOSPC L&B infrastructure failed to accept the event due to lack of disk space etc.,
+ * \retval ENOMEM failed to allocate memory,
+ * \retval ECONNREFUSED cannot connect to the specified L&B Proxy
+ * \retval EAGAIN non blocking return from the call, the event may or may not get logged,
+ * \retval EDG_WLL_ERROR_NOJOBID logging call attempted without assigning jobId to the context.
+ */
+extern int edg_wll_LogEventFile(
+ edg_wll_Context context,
+ edg_wll_EventCode event,
+ char *fmt, ...);
+
+/**
* Instructs interlogger to to deliver all pending events related to current job
* \brief flush events from interlogger
* \note sort of status query more than a command
);
/**
+ * Set a current job for given context.
+ * \note Should be called before any call logging locally to file to be consumed by IL.
+ * \param[in,out] context context to work with
+ * \param[in] job further logging calls are related to this job
+ * \param[in] code sequence code as obtained from previous component
+ * \param[in] user user credentials
+ * \param[in] flags flags on code handling (\see API documentation)
+ */
+extern int edg_wll_SetLoggingJobFile(
+ edg_wll_Context context,
+ glite_jobid_const_t job,
+ const char * code,
+ const char * user,
+ int flags
+);
+
+/**
* Register job with L&B service.
* Done via logging REGJOB event directly to LB server (the connection is asynchronous through GSS)
* - may generate subjob id's and create the parent-children associations,
#include "prod_proto.h"
#include "consumer.h" // for QuerySequenceCode
+#define FCNTL_ATTEMPTS 5
+#define FCNTL_TIMEOUT 1
+#define DEFAULT_SOCKET "/tmp/interlogger.sock"
+
#ifdef FAKE_VERSION
int edg_wll_DoLogEvent(edg_wll_Context ctx, edg_wll_LogLine logline);
int edg_wll_DoLogEventServer(edg_wll_Context ctx, int flags, edg_wll_LogLine logline);
}
+/**
+ *----------------------------------------------------------------------
+ * Save already formatted ULM string to event file
+ * and notify IL through local socket
+ * \brief save message to file, notify IL
+ * \param[in,out] ctx context to work with,
+ * \param[in] logline formated ULM string
+ *----------------------------------------------------------------------
+ */
+int edg_wll_DoLogEventFile(
+ edg_wll_Context ctx,
+ edg_wll_LogLine logline)
+{
+
+ long filepos;
+ char *jobid_s,
+ *event_file = NULL;
+ int err = 0;
+
+#define _err(n) { err = n; goto out; }
+
+ edg_wll_ResetError(ctx);
+
+ jobid_s = edg_wlc_JobIdGetUnique(ctx->p_jobid);
+ if ( !jobid_s ) {
+ _err(edg_wll_SetError(ctx, ENOMEM, "edg_wlc_JobIdGetUnique()"));
+ }
+
+ asprintf(&event_file, "%s.%s",
+ ctx->p_event_file_prefix ? ctx->p_event_file_prefix : EDG_WLL_LOG_PREFIX_DEFAULT,
+ jobid_s);
+ if ( !event_file ) {
+ _err(edg_wll_SetError(ctx, ENOMEM, "asprintf()"));
+ }
+
+ if ( edg_wll_log_event_write(ctx, event_file, logline,
+ (ctx->p_tmp_timeout.tv_sec > FCNTL_ATTEMPTS ?
+ ctx->p_tmp_timeout.tv_sec : FCNTL_ATTEMPTS),
+ FCNTL_TIMEOUT, &filepos) ) {
+
+ _err(edg_wll_UpdateError(ctx, 0, "edg_wll_log_event_write()"));
+ }
+
+ if ( edg_wll_log_event_send(ctx,
+ ctx->p_il_sock ? ctx->p_il_sock : DEFAULT_SOCKET,
+ filepos,
+ logline, strlen(logline), 1, &ctx->p_tmp_timeout) ) {
+ _err(edg_wll_UpdateError(ctx, EDG_WLL_IL_PROTO, "edg_wll_log_event_send()"));
+ }
+
+out:
+ if ( jobid_s ) free(jobid_s);
+ if ( event_file ) free(event_file);
+
+ return handle_errors(ctx, err, "edg_wll_DoLogEventFile()");
+}
+
#endif /* FAKE_VERSION */
/**
}
/* TODO: merge - add always, probably new ctx->p_user
has this already been agreed? */
- if ( ( (flags & EDG_WLL_LOGFLAG_PROXY) || (flags & EDG_WLL_LOGFLAG_DIRECT) ) &&
- (ctx->p_user_lbproxy) ) {
+ if ( ( (flags & EDG_WLL_LOGFLAG_PROXY)
+ || (flags & EDG_WLL_LOGFLAG_DIRECT)
+ || (flags & EDG_WLL_LOGFLAG_FILE) ) &&
+ (ctx->p_user_lbproxy) ) {
if (trio_asprintf(&dguser,EDG_WLL_FORMAT_USER,ctx->p_user_lbproxy) == -1) {
edg_wll_SetError(ctx,ret = ENOMEM,"edg_wll_FormatLogLine(): trio_asprintf() error");
goto edg_wll_formatlogline_end;
* EDG_WLL_LOGFLAG_LOCAL - local-logger
* EDG_WLL_LOGFLAG_PROXY - lbproxy
* EDG_WLL_LOGFLAG_DIRECT - bkserver
+ * EDG_WLL_LOGFLAG_FILE - local file (IL)
* \param[in] event type of the event,
* \param[in] fmt printf()-like format string,
* \param[in] fmt_args event specific values/data according to fmt.
int err_store;
char *err_desc_store = NULL;
- if ((flags & (EDG_WLL_LOGFLAG_LOCAL|EDG_WLL_LOGFLAG_PROXY|EDG_WLL_LOGFLAG_DIRECT)) == 0) {
+ if ((flags & (EDG_WLL_LOGFLAG_LOCAL|EDG_WLL_LOGFLAG_PROXY|EDG_WLL_LOGFLAG_DIRECT|EDG_WLL_LOGFLAG_FILE)) == 0) {
return edg_wll_SetError(ctx,ret = EINVAL,"edg_wll_LogEventMaster(): no known flag specified");
}
ret = edg_wll_DoLogEventServer(ctx, flags, out);
if (ret) goto edg_wll_logeventmaster_end;
}
+ if (flags & EDG_WLL_LOGFLAG_FILE) {
+ ret = edg_wll_DoLogEventFile(ctx, out);
+ if (ret) goto edg_wll_logeventmaster_end;
+ }
#endif
edg_wll_logeventmaster_end:
* EDG_WLL_LOGFLAG_LOCAL - local-logger
* EDG_WLL_LOGFLAG_PROXY - lbproxy
* EDG_WLL_LOGFLAG_DIRECT - bkserver
+ * EDG_WLL_LOGFLAG_FILE - file (IL)
* \param[in] event type of the event,
* \param[in] fmt printf()-like format string,
* \param[in] ... event specific values/data according to fmt.
}
/**
+ *----------------------------------------------------------------------
+ * Formats a logging message and stores it to local file to be delivered by IL.
+ * \brief generic asynchronous logging function
+ * \note simple wrapper around edg_wll_LogEventMaster()
+ *----------------------------------------------------------------------
+ */
+int edg_wll_LogEventFile(
+ edg_wll_Context ctx,
+ edg_wll_EventCode event,
+ char *fmt, ...)
+{
+ int ret=0;
+ va_list fmt_args;
+
+ edg_wll_ResetError(ctx);
+
+ va_start(fmt_args,fmt);
+ ret=edg_wll_LogEventMasterVa(ctx,EDG_WLL_LOGFLAG_FILE,
+ event,fmt,fmt_args);
+ if (ret) edg_wll_UpdateError(ctx,0,"edg_wll_LogEventFile(): ");
+ va_end(fmt_args);
+
+ return edg_wll_Error(ctx,NULL,NULL);
+}
+
+/**
*-----------------------------------------------------------------------
* Instructs interlogger to to deliver all pending events related to current job
* \brief flush events from interlogger
}
/* add user credentials to context */
- if ((logging_flags & EDG_WLL_LOGFLAG_PROXY) && user) {
+ if (user && ((logging_flags & EDG_WLL_LOGFLAG_PROXY)
+ ||(logging_flags & EDG_WLL_LOGFLAG_FILE))) {
edg_wll_SetParamString(ctx, EDG_WLL_PARAM_LBPROXY_USER, user);
} else {
edg_wll_GssStatus gss_stat;
return edg_wll_SetLoggingJobMaster(ctx,job,code,user,seq_code_flags,EDG_WLL_LOGFLAG_PROXY);
}
+int edg_wll_SetLoggingJobFile(
+ edg_wll_Context ctx,
+ glite_jobid_const_t job,
+ const char *code,
+ const char *user,
+ int seq_code_flags)
+{
+ return edg_wll_SetLoggingJobMaster(ctx,job,code,user,seq_code_flags,EDG_WLL_LOGFLAG_FILE);
+}
+
/**
*-----------------------------------------------------------------------
* Master function for registering a job with L&B service.
my $funcproxy = $func . "Proxy";
my $funcc = $func . "CODETOREPLACE"; # name of generated CODE function
my $funccproxy = $funcc . "Proxy";
+ my $funcfile = $func . "File";
+ my $funccfile = $funcc . "File";
my $p = "edg_wll_Context context"; # parameters of generated function
my $pc = $p; # parameters of generated CODE function
my $q = "context,EDG_WLL_EVENT_$tu,EDG_WLL_FORMAT_$tu"; # parameters for LogEvent called in generated function
my $qc = $q; # parameters for LogEvent called in generated CODE function
my $text = ""; # whole text for generated function
my $textproxy = ""; # whole text for generated CODE function
+ my $textfile = "";
my $doc = " * \\param[in,out] context\tcontext to work with, \n"; # parameters description for generated function
my $docc = $doc; # parameters description for generated CODE function
* $funcproxy - simple wrapper around edg_wll_LogEventProxy for event $t
*
};
+ $textfile = qq{
+/**
+ * \\brief $funcfile
+ *
+ * $funcfile - simple wrapper around edg_wll_LogEventFile for event $t
+ *
+};
if ($PRINTDOC) {
$text = $text . $doc . " * \\see edg_wll_LogEvent()\n";
- $textproxy = $textproxy . $doc . "* \\see edg_wll_LogEventProxy()\n"
+ $textproxy = $textproxy . $doc . "* \\see edg_wll_LogEventProxy()\n";
+ $textfile = $textfile . $doc . " * \\see edg_wll_LogEventFile()\n";
}
$text = $text . " */\n";
$textproxy = $textproxy . " */\n";
+ $textfile = $textfile . " */\n";
if ($PRINTPROTOTYPESONLY) {
$text = $text . "\nextern int $func($p);\n";
$textproxy = $textproxy . "\nextern int $funcproxy($p);\n";
+ $textfile = $textfile . "\nextern int $funcfile($p);\n";
} else {
$text = $text . qq{
int $func($p)
return ret;
\}
};
+ $textfile = $textfile . qq{
+int $funcfile($p)
+\{
+$decl
+ ret = edg_wll_LogEventFile($q);
+$free
+ return ret;
+\}
+};
}
gen "$text";
gen "$textproxy";
+ gen "$textfile";
#
# generate also CODE functions:
my $code = uc $_->{name};
my $funccc = $funcc; $funccc =~ s/CODETOREPLACE/$code/g;
my $funcccproxy = $funccproxy; $funcccproxy =~ s/CODETOREPLACE/$code/g;
+ my $funcccfile = $funccfile; $funcccfile =~ s/CODETOREPLACE/$code/g;
my $qcc = $qc; $qcc =~ s/CODETOREPLACE/"$code"/g;
my $textc = qq{
/**
* $funcccproxy - simple wrapper around edg_wll_LogEventProxy for event $t, $fn $code
*
};
+ my $textcfile = qq{
+/**
+ * \\brief $funcccfile
+ *
+ * $funcccfile - simple wrapper around edg_wll_LogEventFile for event $t, $fn $code
+ *
+};
if ($PRINTDOC) {
$textc = $textc . $docc . " * \\see edg_wll_LogEvent()\n";
$textcproxy = $textcproxy . $docc . " * \\see edg_wll_LogEventProxy()\n";
+ $textcfile = $textcfile . $docc . " * \\see edg_wll_LogEventFile()\n";
}
$textc = $textc . " */\n";
$textcproxy = $textcproxy . " */\n";
+ $textcfile = $textcfile . " */\n";
if ($PRINTPROTOTYPESONLY) {
$textc = $textc . "\nextern int $funccc($pc);\n";
$textcproxy = $textcproxy . "\nextern int $funcccproxy($pc);\n";
+ $textcfile = $textcfile . "\nextern int $funcccfile($pc);\n";
} else {
$textc = $textc . qq{
int $funccc($pc)
return ret;
\}
};
+ $textcfile = $textcfile . qq{
+int $funcccfile($pc)
+\{
+$decl
+ ret = edg_wll_LogEventFile($qcc);
+$free
+ return ret;
+\}
+};
}
gen "$textc";
gen "$textcproxy";
+ gen "$textcfile";
} # for codes
} # if
} # for getFields