Project

General

Profile

1 2096 jones
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2004 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author$'
7
 *     '$Date$'
8
 * '$Revision$'
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 */
24
package edu.ucsb.nceas.metacat;
25
26 2104 jones
import java.sql.PreparedStatement;
27 2111 jones
import java.sql.ResultSet;
28 2096 jones
import java.sql.SQLException;
29 2104 jones
import java.sql.Timestamp;
30 6595 leinfelder
import java.util.ArrayList;
31 2096 jones
import java.util.Date;
32 8464 leinfelder
import java.util.HashMap;
33 6595 leinfelder
import java.util.List;
34 8464 leinfelder
import java.util.Map;
35 7285 leinfelder
import java.util.Vector;
36 2096 jones
37 2663 sgarg
import org.apache.log4j.Logger;
38 7285 leinfelder
import org.dataone.service.types.v1.Event;
39
import org.dataone.service.types.v1.Identifier;
40
import org.dataone.service.types.v1.Log;
41
import org.dataone.service.types.v1.LogEntry;
42
import org.dataone.service.types.v1.NodeReference;
43
import org.dataone.service.types.v1.Subject;
44 6944 leinfelder
import org.dataone.service.util.DateTimeMarshaller;
45 2663 sgarg
46 5015 daigle
import edu.ucsb.nceas.metacat.database.DBConnection;
47
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
48 7437 leinfelder
import edu.ucsb.nceas.metacat.database.DatabaseService;
49 8464 leinfelder
import edu.ucsb.nceas.metacat.index.MetacatSolrIndex;
50 7285 leinfelder
import edu.ucsb.nceas.metacat.properties.PropertyService;
51 7409 leinfelder
import edu.ucsb.nceas.metacat.util.DocumentUtil;
52 7285 leinfelder
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
53 5015 daigle
54 2096 jones
/**
55
 * EventLog is used to intialize and store a log of events that occur in an
56
 * application. The events are registered with the logger as they occur, but
57
 * EventLog writes them to permenant storage when it is most convenient or
58
 * efficient. EventLog is a Singleton as there should always be only one object
59
 * for these logging events.
60
 *
61
 * TODO: Logging to the database needn't be synchronous with the event.
62
 * Instead, a separate thread can be launched that periodically sleeps and only
63
 * wakes periodically to see if metacat is idle.  The log event can be cached
64
 * and inserted later when the thread wakes and finds metacat idle.
65
 *
66
 * TODO: Write a function that archives a part of the log table to an
67
 * external text file so that the log table doesn't get to big.  This
68
 * function should be able to be called manually or on a schedule.
69
 *
70
 * TODO: Write an access function that returns an XML report for a
71
 * specific subset of events.  Users should be able to query on
72
 * principal, docid/rev, date, event, and possibly other fields.
73
 *
74
 * @author jones
75
 */
76
public class EventLog
77
{
78
    /**
79
     * The single instance of the event log that is always returned.
80
     */
81
    private static EventLog self = null;
82 2663 sgarg
    private Logger logMetacat = Logger.getLogger(EventLog.class);
83 2096 jones
84
    /**
85
     * A private constructor that initializes the class when getInstance() is
86
     * called.
87
     */
88
    private EventLog()
89
    {
90
    }
91
92
    /**
93
     * Return the single instance of the event log after initializing it if it
94
     * wasn't previously initialized.
95
     *
96
     * @return the single EventLog instance
97
     */
98
    public static EventLog getInstance()
99
    {
100
        if (self == null) {
101
            self = new EventLog();
102
        }
103
        return self;
104
    }
105
106
    /**
107
     * Log an event of interest to the application. The information logged can
108
     * include basic identification information about the principal or computer
109
     * that initiated the event.
110
     *
111 2099 jones
     * @param ipAddress the internet protocol address for the event
112 6542 leinfelder
     * @param userAgent the agent making the request
113 2099 jones
	 * @param principal the principal for the event (a username, etc)
114
	 * @param docid the identifier of the document to which the event applies
115
	 * @param event the string code for the event
116 2096 jones
     */
117 6542 leinfelder
    public void log(String ipAddress, String userAgent, String principal, String docid, String event) {
118
        EventLogData logData = new EventLogData(ipAddress, principal, docid, event);
119 2096 jones
        insertLogEntry(logData);
120 8464 leinfelder
121
        // update the event information in the index
122
        try {
123
	        String localId = DocumentUtil.getSmartDocId(docid);
124
			int rev = DocumentUtil.getRevisionFromAccessionNumber(docid);
125
126
	        String guid = IdentifierManager.getInstance().getGUID(localId, rev);
127
	        Identifier pid = new Identifier();
128
	        pid.setValue(guid);
129
130
	        // submit for indexing
131
	        MetacatSolrIndex.getInstance().submit(pid, null, this.getIndexFields(pid, event));
132
133
        } catch (Exception e) {
134
        	logMetacat.error("Could not update event index information", e);
135
        }
136 2096 jones
    }
137 2099 jones
138 8464 leinfelder
    public Map<String, List<Object>> getIndexFields(Identifier pid, String event) {
139
    	// update the search index for the event
140
        try {
141
142
        	Event d1Event = Event.convert(event);
143 8596 leinfelder
        	if (d1Event != null) {
144
145
	        	String fieldName = d1Event.xmlValue() + "_count_i";
146
	        	int eventCount = 0;
147
148
	        	String docid = IdentifierManager.getInstance().getLocalId(pid.getValue());
149
	        	Log eventLog = this.getD1Report(null, null, new String[] {docid}, d1Event, null, null, false, 0, 0);
150
	        	eventCount = eventLog.getTotal();
151
152
		        List<Object> values = new ArrayList<Object>();
153
				values.add(eventCount);
154
		        Map<String, List<Object>> fields = new HashMap<String, List<Object>>();
155
		        fields.put(fieldName, values);
156
157
		        return fields;
158
        	}
159 8464 leinfelder
160
        } catch (Exception e) {
161 8596 leinfelder
        	logMetacat.error("Could not update event index information on pid: " + pid.getValue() + " for event: " + event, e);
162 8464 leinfelder
        }
163 8596 leinfelder
        // default if we can't find the event information
164
    	return null;
165
166 8464 leinfelder
    }
167
168 2096 jones
    /**
169
     * Insert a single log event record to the database.
170
     *
171
     * @param logData the data to be logged when an event occurs
172
     */
173
    private void insertLogEntry(EventLogData logData)
174
    {
175
        String insertString = "insert into access_log"
176 6542 leinfelder
                + "(ip_address, user_agent, principal, docid, "
177 2096 jones
                + "event, date_logged) "
178 6595 leinfelder
                + "values ( ?, ?, ?, ?, ?, ? )";
179
180 2096 jones
        DBConnection dbConn = null;
181
        int serialNumber = -1;
182
        try {
183
            // Get a database connection from the pool
184 2111 jones
            dbConn = DBConnectionPool.getDBConnection("EventLog.insertLogEntry");
185 2096 jones
            serialNumber = dbConn.getCheckOutSerialNumber();
186
187
            // Execute the insert statement
188 2104 jones
            PreparedStatement stmt = dbConn.prepareStatement(insertString);
189 6595 leinfelder
190
            stmt.setString(1, logData.getIpAddress());
191
            stmt.setString(2, logData.getUserAgent());
192
            stmt.setString(3, logData.getPrincipal());
193
            stmt.setString(4, logData.getDocid());
194
            stmt.setString(5, logData.getEvent());
195
            stmt.setTimestamp(6, new Timestamp(new Date().getTime()));
196 2104 jones
            stmt.executeUpdate();
197 2096 jones
            stmt.close();
198
        } catch (SQLException e) {
199 2663 sgarg
        	logMetacat.error("Error while logging event to database: "
200
                    + e.getMessage());
201 2096 jones
        } finally {
202
            // Return database connection to the pool
203
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
204
        }
205
    }
206 2110 jones
207
    /**
208
     * Get a report of the log events that match a set of filters.  The
209 2111 jones
     * filter parameters can be null; log records are subset based on
210 2110 jones
     * non-null filter parameters.
211
     *
212
     * @param ipAddress the internet protocol address for the event
213
	 * @param principal the principal for the event (a username, etc)
214
	 * @param docid the identifier of the document to which the event applies
215
	 * @param event the string code for the event
216 2111 jones
	 * @param startDate beginning of date range for query
217
	 * @param endDate end of date range for query
218
	 * @return an XML-formatted report of the access log entries
219 2110 jones
     */
220 2111 jones
    public String getReport(String[] ipAddress, String[] principal, String[] docid,
221 5693 leinfelder
            String[] event, Timestamp startDate, Timestamp endDate, boolean anonymous)
222 2110 jones
    {
223 2111 jones
        StringBuffer resultDoc = new StringBuffer();
224
        StringBuffer query = new StringBuffer();
225 6542 leinfelder
        query.append("select entryid, ip_address, user_agent, principal, docid, "
226 2111 jones
            + "event, date_logged from access_log");
227
//                        + ""
228
//                        + "event, date_logged) " + "values (" + "'"
229
//                        + logData.getIpAddress() + "', " + "'"
230
//                        + logData.getPrincipal() + "', " + "'"
231
//                        + logData.getDocid() + "', " + "'" + logData.getEvent()
232
//                        + "', " + " ? " + ")";
233
        if (ipAddress != null || principal != null || docid != null
234
                        || event != null || startDate != null || endDate != null) {
235
            query.append(" where ");
236
        }
237
        boolean clauseAdded = false;
238
        int startIndex = 0;
239
        int endIndex = 0;
240
241 6595 leinfelder
        List<String> paramValues = new ArrayList<String>();
242 2111 jones
        if (ipAddress != null) {
243 6595 leinfelder
        	query.append("ip_address in (");
244
        	for (int i = 0; i < ipAddress.length; i++) {
245
        		if (i > 0) {
246
            		query.append(", ");
247
        		}
248
        		query.append("?");
249
        		paramValues.add(ipAddress[i]);
250
        	}
251
        	query.append(") ");
252 2111 jones
            clauseAdded = true;
253
        }
254
        if (principal != null) {
255 7309 leinfelder
        	if (clauseAdded) {
256
                query.append(" and ");
257
            }
258 6595 leinfelder
        	query.append("principal in (");
259
        	for (int i = 0; i < principal.length; i++) {
260
        		if (i > 0) {
261
            		query.append(", ");
262
        		}
263
        		query.append("?");
264
        		paramValues.add(principal[i]);
265
        	}
266
        	query.append(") ");
267 2111 jones
            clauseAdded = true;
268
        }
269
        if (docid != null) {
270 7309 leinfelder
        	if (clauseAdded) {
271
                query.append(" and ");
272
            }
273 6595 leinfelder
        	query.append("docid in (");
274
        	for (int i = 0; i < docid.length; i++) {
275
        		if (i > 0) {
276
            		query.append(", ");
277
        		}
278
        		query.append("?");
279 7409 leinfelder
        		String fullDocid = docid[i];
280
        		// allow docid without revision - look up latest version
281
        		try {
282
        			fullDocid = DocumentUtil.appendRev(fullDocid);
283
        		} catch (Exception e) {
284
					// just warn about this
285
        			logMetacat.warn("Could not check docid for revision: " + fullDocid, e);
286
				}
287
        		paramValues.add(fullDocid);
288 6595 leinfelder
        	}
289
        	query.append(") ");
290 2111 jones
            clauseAdded = true;
291
        }
292
        if (event != null) {
293 7309 leinfelder
        	if (clauseAdded) {
294
                query.append(" and ");
295
            }
296 6595 leinfelder
        	query.append("event in (");
297
        	for (int i = 0; i < event.length; i++) {
298
        		if (i > 0) {
299
            		query.append(", ");
300
        		}
301
        		query.append("?");
302
        		paramValues.add(event[i]);
303
        	}
304
        	query.append(") ");
305 2111 jones
            clauseAdded = true;
306
        }
307
        if (startDate != null) {
308
            if (clauseAdded) {
309
                query.append(" and ");
310
            }
311 7057 leinfelder
            query.append("date_logged >= ?");
312 2111 jones
            clauseAdded = true;
313
            startIndex++;
314
        }
315
        if (endDate != null) {
316
            if (clauseAdded) {
317
                query.append(" and ");
318
            }
319
            query.append("date_logged < ?");
320
            clauseAdded = true;
321
            endIndex = startIndex + 1;
322
        }
323
        DBConnection dbConn = null;
324
        int serialNumber = -1;
325
        try {
326
            // Get a database connection from the pool
327
            dbConn = DBConnectionPool.getDBConnection("EventLog.getReport");
328
            serialNumber = dbConn.getCheckOutSerialNumber();
329
330 2113 jones
            // Execute the query statement
331 2111 jones
            PreparedStatement stmt = dbConn.prepareStatement(query.toString());
332 6595 leinfelder
            //set the param values
333
            int parameterIndex = 1;
334
            for (String val: paramValues) {
335 7309 leinfelder
            	stmt.setString(parameterIndex++, val);
336 6595 leinfelder
            }
337 6598 leinfelder
            if (startDate != null) {
338
                stmt.setTimestamp(parameterIndex++, startDate);
339 2111 jones
            }
340 6598 leinfelder
            if (endDate != null) {
341
            	stmt.setTimestamp(parameterIndex++, endDate);
342 2111 jones
            }
343
            stmt.execute();
344
            ResultSet rs = stmt.getResultSet();
345 2113 jones
            //process the result and return it as an XML document
346 2111 jones
            resultDoc.append("<?xml version=\"1.0\"?>\n");
347
            resultDoc.append("<log>\n");
348
            while (rs.next()) {
349 5693 leinfelder
                resultDoc.append(
350
                		generateXmlRecord(
351
                				rs.getString(1), //id
352
                				anonymous ? "" : rs.getString(2), //ip
353 6542 leinfelder
                				rs.getString(3), //userAgent
354
                				anonymous ? "" : rs.getString(4), //principal
355 5693 leinfelder
                                rs.getString(5),
356 6542 leinfelder
                                rs.getString(6),
357
                                rs.getTimestamp(7)));
358 2111 jones
            }
359
            resultDoc.append("</log>");
360
            stmt.close();
361
        } catch (SQLException e) {
362 2663 sgarg
        	logMetacat.info("Error while logging event to database: "
363
                            + e.getMessage());
364 2111 jones
        } finally {
365
            // Return database connection to the pool
366
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
367
        }
368
        return resultDoc.toString();
369 2110 jones
    }
370 2111 jones
371 7285 leinfelder
372
373
    public Log getD1Report(String[] ipAddress, String[] principal, String[] docid,
374
            Event event, Timestamp startDate, Timestamp endDate, boolean anonymous, Integer start, Integer count)
375
    {
376
377
        Log log = new Log();
378
379
    	NodeReference memberNode = new NodeReference();
380
        String nodeId = "localhost";
381
        try {
382
            nodeId = PropertyService.getProperty("dataone.nodeId");
383
        } catch (PropertyNotFoundException e1) {
384
            // TODO Auto-generated catch block
385
            e1.printStackTrace();
386
        }
387
        memberNode.setValue(nodeId);
388
389 7451 leinfelder
        String countClause = "select count(*) ";
390
        String fieldsClause = "select " +
391 7285 leinfelder
        		"entryid, " +
392
        		"id.guid as identifier, " +
393
        		"ip_address, " +
394
        		"user_agent, " +
395
        		"principal, " +
396
        		"case " +
397
        		"	when event = 'insert' then 'create' " +
398
        		"	else event " +
399
        		"end as event, " +
400 7451 leinfelder
        		"date_logged ";
401
402
        StringBuffer queryWhereClause = new StringBuffer();
403
        queryWhereClause.append(
404 7285 leinfelder
        		"from access_log al, identifier id " +
405
        		"where al.docid = id.docid||'.'||id.rev "
406
        );
407
408 7287 leinfelder
        boolean clauseAdded = true;
409 7285 leinfelder
410
        List<String> paramValues = new ArrayList<String>();
411
        if (ipAddress != null) {
412 7309 leinfelder
        	if (clauseAdded) {
413 7451 leinfelder
                queryWhereClause.append(" and ");
414 7309 leinfelder
            }
415 7451 leinfelder
        	queryWhereClause.append("ip_address in (");
416 7285 leinfelder
        	for (int i = 0; i < ipAddress.length; i++) {
417
        		if (i > 0) {
418 7451 leinfelder
            		queryWhereClause.append(", ");
419 7285 leinfelder
        		}
420 7451 leinfelder
        		queryWhereClause.append("?");
421 7285 leinfelder
        		paramValues.add(ipAddress[i]);
422
        	}
423 7451 leinfelder
        	queryWhereClause.append(") ");
424 7285 leinfelder
            clauseAdded = true;
425
        }
426
        if (principal != null) {
427 7309 leinfelder
        	if (clauseAdded) {
428 7451 leinfelder
                queryWhereClause.append(" and ");
429 7309 leinfelder
            }
430 7451 leinfelder
        	queryWhereClause.append("principal in (");
431 7285 leinfelder
        	for (int i = 0; i < principal.length; i++) {
432
        		if (i > 0) {
433 7451 leinfelder
            		queryWhereClause.append(", ");
434 7285 leinfelder
        		}
435 7451 leinfelder
        		queryWhereClause.append("?");
436 7285 leinfelder
        		paramValues.add(principal[i]);
437
        	}
438 7451 leinfelder
        	queryWhereClause.append(") ");
439 7285 leinfelder
            clauseAdded = true;
440
        }
441
        if (docid != null) {
442 7309 leinfelder
        	if (clauseAdded) {
443 7451 leinfelder
                queryWhereClause.append(" and ");
444 7309 leinfelder
            }
445 7451 leinfelder
        	queryWhereClause.append("al.docid in (");
446 7285 leinfelder
        	for (int i = 0; i < docid.length; i++) {
447
        		if (i > 0) {
448 7451 leinfelder
            		queryWhereClause.append(", ");
449 7285 leinfelder
        		}
450 7451 leinfelder
        		queryWhereClause.append("?");
451 7285 leinfelder
        		paramValues.add(docid[i]);
452
        	}
453 7451 leinfelder
        	queryWhereClause.append(") ");
454 7285 leinfelder
            clauseAdded = true;
455
        }
456
        if (event != null) {
457 7309 leinfelder
        	if (clauseAdded) {
458 7451 leinfelder
                queryWhereClause.append(" and ");
459 7309 leinfelder
            }
460 7451 leinfelder
        	queryWhereClause.append("event in (");
461
    		queryWhereClause.append("?");
462 7287 leinfelder
    		String eventString = event.xmlValue();
463 7285 leinfelder
    		if (event.equals(Event.CREATE)) {
464
    			eventString = "insert";
465
    		}
466
    		paramValues.add(eventString);
467 7451 leinfelder
        	queryWhereClause.append(") ");
468 7285 leinfelder
            clauseAdded = true;
469
        }
470 7450 leinfelder
        else {
471 7437 leinfelder
	        if (clauseAdded) {
472 7451 leinfelder
	            queryWhereClause.append(" and ");
473 7437 leinfelder
	        }
474 7451 leinfelder
	    	queryWhereClause.append("event in (");
475 7437 leinfelder
	    	for (int i = 0; i < Event.values().length; i++) {
476
	    		if (i > 0) {
477 7451 leinfelder
	        		queryWhereClause.append(", ");
478 7437 leinfelder
	    		}
479 7451 leinfelder
	    		queryWhereClause.append("?");
480 7450 leinfelder
	    		Event e = Event.values()[i];
481
	    		String eventString = e.xmlValue();
482
	    		if (e.equals(Event.CREATE)) {
483
	    			eventString = "insert";
484
	    		}
485
	    		paramValues.add(eventString);
486 7437 leinfelder
	    	}
487 7451 leinfelder
	    	queryWhereClause.append(") ");
488 7437 leinfelder
	        clauseAdded = true;
489
        }
490 7285 leinfelder
        if (startDate != null) {
491
            if (clauseAdded) {
492 7451 leinfelder
                queryWhereClause.append(" and ");
493 7285 leinfelder
            }
494 7451 leinfelder
            queryWhereClause.append("date_logged >= ?");
495 7285 leinfelder
            clauseAdded = true;
496
        }
497
        if (endDate != null) {
498
            if (clauseAdded) {
499 7451 leinfelder
                queryWhereClause.append(" and ");
500 7285 leinfelder
            }
501 7451 leinfelder
            queryWhereClause.append("date_logged < ?");
502 7285 leinfelder
            clauseAdded = true;
503
        }
504 7437 leinfelder
505
        // order by
506 7451 leinfelder
        String orderByClause = " order by entryid ";
507 7437 leinfelder
508 7451 leinfelder
        // select the count
509
        String countQuery = countClause + queryWhereClause.toString();
510
511
		// select the fields
512
        String pagedQuery = DatabaseService.getInstance().getDBAdapter().getPagedQuery(fieldsClause + queryWhereClause.toString() + orderByClause, start, count);
513 7437 leinfelder
514 7285 leinfelder
        DBConnection dbConn = null;
515
        int serialNumber = -1;
516
        try {
517
            // Get a database connection from the pool
518
            dbConn = DBConnectionPool.getDBConnection("EventLog.getD1Report");
519
            serialNumber = dbConn.getCheckOutSerialNumber();
520
521
            // Execute the query statement
522 7451 leinfelder
            PreparedStatement fieldsStmt = dbConn.prepareStatement(pagedQuery);
523
            PreparedStatement countStmt = dbConn.prepareStatement(countQuery);
524
525 7285 leinfelder
            //set the param values
526
            int parameterIndex = 1;
527
            for (String val: paramValues) {
528 7451 leinfelder
            	countStmt.setString(parameterIndex, val);
529
            	fieldsStmt.setString(parameterIndex, val);
530
            	parameterIndex++;
531 7285 leinfelder
            }
532
            if (startDate != null) {
533 7451 leinfelder
            	countStmt.setTimestamp(parameterIndex, startDate);
534
                fieldsStmt.setTimestamp(parameterIndex, startDate);
535
            	parameterIndex++;
536 7285 leinfelder
            }
537
            if (endDate != null) {
538 7451 leinfelder
            	countStmt.setTimestamp(parameterIndex, endDate);
539
            	fieldsStmt.setTimestamp(parameterIndex, endDate);
540
            	parameterIndex++;
541 7285 leinfelder
            }
542 7451 leinfelder
543
            // for the return Log list
544 7285 leinfelder
            List<LogEntry> logs = new Vector<LogEntry>();
545
546 7451 leinfelder
            // get the fields form the query
547
            if (count != 0) {
548
	            fieldsStmt.execute();
549
	            ResultSet rs = fieldsStmt.getResultSet();
550
	            //process the result and return it
551
	            while (rs.next()) {
552
	            	LogEntry logEntry = new LogEntry();
553
	            	logEntry.setEntryId(rs.getString(1));
554
555
	            	Identifier identifier = new Identifier();
556
	            	identifier.setValue(rs.getString(2));
557
					logEntry.setIdentifier(identifier);
558
559
	            	logEntry.setIpAddress(anonymous ? "N/A" : rs.getString(3));
560
	            	String userAgent = "N/A";
561
	            	if (rs.getString(4) != null) {
562
	            		userAgent = rs.getString(4);
563
	            	}
564
	            	logEntry.setUserAgent(userAgent);
565
566
	            	Subject subject = new Subject();
567
	            	subject.setValue(anonymous ? "N/A" : rs.getString(5));
568
					logEntry.setSubject(subject);
569
570
					String logEventString = rs.getString(6);
571
					Event logEvent = Event.convert(logEventString );
572
					if (logEvent == null) {
573
						logMetacat.info("Skipping uknown DataONE Event type: " + logEventString);
574
						continue;
575
					}
576
					logEntry.setEvent(logEvent);
577
					logEntry.setDateLogged(rs.getTimestamp(7));
578
579
					logEntry.setNodeIdentifier(memberNode);
580
					logs.add(logEntry);
581
	            }
582
	            fieldsStmt.close();
583 7285 leinfelder
            }
584
585 7451 leinfelder
            // set what we have
586
            log.setLogEntryList(logs);
587 7285 leinfelder
		    log.setStart(start);
588
		    log.setCount(logs.size());
589 7451 leinfelder
590
			// get total for out query
591
		    int total = 0;
592
            countStmt.execute();
593
            ResultSet countRs = countStmt.getResultSet();
594
            if (countRs.next()) {
595
            	total = countRs.getInt(1);
596
            }
597
            countStmt.close();
598 7285 leinfelder
		    log.setTotal(total);
599
600
        } catch (SQLException e) {
601 7287 leinfelder
        	logMetacat.error("Error while getting log events: " + e.getMessage(), e);
602 7285 leinfelder
        } finally {
603
            // Return database connection to the pool
604
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
605
        }
606
        return log;
607
    }
608
609 2111 jones
    /**
610
     * Format each returned log record as an XML structure.
611
     *
612
     * @param entryId the identifier of the log entry
613
     * @param ipAddress the internet protocol address for the event
614 6542 leinfelder
     * @param the agent making the request
615 2111 jones
	 * @param principal the principal for the event (a username, etc)
616
	 * @param docid the identifier of the document to which the event applies
617
	 * @param event the string code for the event
618
     * @param dateLogged the date on which the event occurred
619
     * @return String containing the formatted XML
620
     */
621 6542 leinfelder
    private String generateXmlRecord(String entryId, String ipAddress, String userAgent,
622 2113 jones
            String principal, String docid, String event, Timestamp dateLogged)
623 2111 jones
    {
624
        StringBuffer rec = new StringBuffer();
625
        rec.append("<logEntry>");
626 2113 jones
        rec.append(generateXmlElement("entryid", entryId));
627
        rec.append(generateXmlElement("ipAddress", ipAddress));
628 6542 leinfelder
        rec.append(generateXmlElement("userAgent", userAgent));
629 2113 jones
        rec.append(generateXmlElement("principal", principal));
630
        rec.append(generateXmlElement("docid", docid));
631
        rec.append(generateXmlElement("event", event));
632 6944 leinfelder
        rec.append(generateXmlElement("dateLogged", DateTimeMarshaller.serializeDateToUTC(dateLogged)));
633 2111 jones
        rec.append("</logEntry>\n");
634
635
        return rec.toString();
636
    }
637
638
    /**
639
     * Return an XML formatted element for a given name/value pair.
640
     *
641
     * @param name the name of the xml element
642
     * @param value the content of the xml element
643
     * @return the formatted XML element as a String
644
     */
645 2113 jones
    private String generateXmlElement(String name, String value)
646 2111 jones
    {
647
        return "<" + name + ">" + value + "</" + name + ">";
648
    }
649 2096 jones
}