--- /dev/null
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include "glite/jobid/cjobid.h"
+#include "glite/lb/events.h"
+#include "glite/lb/producer.h"
+
+static struct option opts[] = {
+ {"help", 0, NULL, 'h'},
+ {"sock", 1, NULL, 's'},
+ {"jobid", 1, NULL, 'j'},
+ {"user", 1, NULL, 'u'},
+ {"seq", 1, NULL, 'c'},
+ {"name", 1, NULL, 'n'},
+ {"value", 1, NULL, 'v'}
+};
+
+static void usage(char *me)
+{
+ fprintf(stderr, "usage: %s [option]\n"
+ "\t-h, --help Shows this screen.\n"
+ "\t-s, --server LB Proxy socket.\n"
+ "\t-j, --jobid ID of requested job.\n"
+ "\t-u, --user User DN.\n"
+ "\t-c, --seq Sequence code.\n"
+ "\t-n, --name Name of the tag.\n"
+ "\t-v, --value Value of the tag.\n"
+ , me);
+}
+
+
+int main(int argc, char *argv[])
+{
+ char *server, *seq_code, *jobid_s, *user, *name, *value;
+ int opt, err = 0;
+
+
+ server = code = jobid_s = name = value = NULL;
+ while ( (opt = getopt_long(argc, argv, "hs:j:u:c:n:v:", opts, NULL)) != EOF)
+ switch (opt) {
+ case 'h': usage(name); return 0;
+ case 's': server = strdup(optarg); break;
+ case 'j': jobid_s = strdup(optarg); break;
+ case 'u': user = strdup(optarg); break;
+ case 'c': seq_code = strdup(optarg); break;
+ case 'n': name = strdup(optarg); break;
+ case 'v': value = strdup(optarg); break;
+ case '?': usage(name); return 1;
+ }
+
+ if ( !jobid_s ) { fprintf(stderr, "JobId not given\n"); return 1; }
+ if ( !server ) { fprintf(stderr, "LB proxy socket not given\n"); return 1; }
+ if ( !name ) { fprintf(stderr, "Tag name not given\n"); return 1; }
+ if ( !value ) { fprintf(stderr, "Tag value not given\n"); return 1; }
+
+
+ edg_wll_Context ctx;
+ edg_wlc_JobId jobid = NULL;
+
+ if ( (errno = edg_wlc_JobIdParse(jobid_s, &jobid)) ) { perror(jobid_s); return 1; }
+
+ edg_wll_InitContext(&ctx);
+
+ if ( !user ) {
+ /*
+ edg_wll_GssStatus gss_stat;
+
+ if ( edg_wll_gss_acquire_cred_gsi(
+ ctx->p_proxy_filename ? : ctx->p_cert_filename,
+ ctx->p_proxy_filename ? : ctx->p_key_filename,
+ NULL, &gss_stat) ) {
+ fprintf(stderr, "failed to load GSI credentials\n");
+ retrun 1;
+ }
+ */
+ }
+
+ edg_wll_SetParam(ctx, EDG_WLL_PARAM_SOURCE, EDG_WLL_SOURCE_USER_INTERFACE);
+ edg_wll_SetParam(ctx, EDG_WLL_PARAM_LBPROXY_STORE_SOCK, server);
+
+ if (edg_wll_SetLoggingJob(ctx, jobid, seq_code, EDG_WLL_SEQ_NORMAL)) {
+ char *et,*ed;
+ edg_wll_Error(ctx,&et,&ed);
+ fprintf(stderr,"SetLoggingJob(%s,%s): %s (%s)\n",jobid_s,seq_code,et,ed);
+ exit(1);
+ }
+
+ err = edg_wll_LogEvent(ctx,
+ EDG_WLL_EVENT_USERTAG,
+ EDG_WLL_FORMAT_USERTAG,
+ name, value);
+
+ if (err) {
+ char *et,*ed;
+
+ edg_wll_Error(ctx,&et,&ed);
+ fprintf(stderr,"%s: edg_wll_LogEvent*(): %s (%s)\n",
+ argv[0],et,ed);
+ free(et); free(ed);
+ }
+
+ seq_code = edg_wll_GetSequenceCode(ctx);
+ puts(seq_code);
+ free(seq_code);
+
+ edg_wll_FreeContext(ctx);
+
+ return err;
+}
% -*- mode: latex -*-
\section{\LB\ Logging (Producer) API}
-\TODO{Add the list of header files, important functions and data types
-and their description; add fully working (buildable) programing
-examples and use verbatiminput to include the important parts of the
-code.}
-
\label{ProdOverview}
The \LB\ logging API (or producer API) is used to create and deliver
events to the \LB\ server and/or proxy, depending on the function
\begin{tabularx}{\textwidth}{lX}
\bf Function & \bf Delivered to \\
\hline
-\small\verb'edg_wll_Register*(...)' & directly to both \LB\ server and proxy \\
-\small\verb'edg_wll_ChangeACL(...)' & directly to the \LB\ server \\
-\small\verb'edg_wll_LogEventSync(...)' & synchronously through
-locallogger/interlogger to the \LB\ server \\
\small\verb'edg_wll_LogEvent(...)' & asynchronously through
locallogger/interlogger to the \LB\ server \\
+\small\verb'edg_wll_LogEventSync(...)' & synchronously through
+locallogger/interlogger to the \LB\ server \\
\small\verb'edg_wll_LogEventProxy(...)' & through \LB\ proxy to the \LB\ server \\
+\small\verb'edg_wll_Register*(...)' & directly to both \LB\ server and proxy \\
+\small\verb'edg_wll_ChangeACL(...)' & directly to the \LB\ server \\
\end{tabularx}
\end{table}
These general functions take as an argument event format (which
-defines the ULM used) and variable number of arguments corresponding
+defines the ULM string used) and variable number of arguments corresponding
to the given format. For each defined event there is predefined format
string in the form \verb'EDG_WLL_FORMAT_'\textit{EventType}, \eg\
\verb'EDG_WLL_FORMAT_UserTag', as well as three convenience functions
\verb'EDG_WLL_ERROR_NOJOBID' or \verb'EDG_WLL_ERROR_DB_DUP_KEY'.
\subsection{Logging events}
-
-
-
-
-Java binding
+In this section we will give an example how to log an UserTag event to
+the \LB.
+
+First we have to include neccessary headers:
+\lstinputlisting[firstline=8,lastline=10]{prod_example1.c}
+
+Initialize context and set parameters:
+\lstinputlisting[firstline=61,lastline=84]{prod_example1.c}
+
+\TODO{proper setting of sequence codes}
+\lstinputlisting[firstline=86,lastline=91]{prod_example1.c}
+
+Log the event:
+\lstinputlisting[firstline=93,lastline=107]{prod_example1.c}
+
+The \verb'edg_wll_LogEvent()' function is defined as follows:
+\begin{lstlisting}[numbers=none]
+extern int edg_wll_LogEvent(
+ edg_wll_Context context,
+ edg_wll_EventCode event,
+ char *fmt, ...);
+\end{lstlisting}
+If you use this function, you have to provide event code, format
+string and corresponding arguments yourself. The UserTag event has
+only two arguments, tag name and value, but other events require more
+arguments.
+
+Instead of using the generic \verb'edg_wll_LogEvent()', we could also
+write:
+\begin{lstlisting}[firstnumber=92]
+err = edg_wll_LogUserTag(ctx, name, value);
+\end{lstlisting}
+
+\subsection{Java binding}