1 package com.protomatter.syslog; 2 3 52 53 import java.io.*; 54 import java.net.*; 55 import java.sql.*; 56 import java.util.*; 57 import java.text.*; 58 59 import com.protomatter.util.*; 60 61 173 public class DatabaseLog 174 extends BasicLogger 175 { 176 private String driver = null; 177 private String url = null; 178 private Properties props = null; 179 180 private DatabaseLogStatementAdapter statementAdapter = null; 181 182 private int numRetries = 3; 183 184 private Connection conn = null; 185 186 private PreparedStatement stmt = null; 187 188 private int messageWidth = 255; 190 private int detailWidth = 4000; 191 192 private String tablePrefix = ""; 193 194 private Hashtable knownChannels = new Hashtable(); 197 198 private String INSERT_PREFIX = "INSERT INTO "; 199 200 private String INSERT_LOG_SQL = "SYSLOG_LOG (LOG_TIME, SYSLOG_LEVEL, HOST, LOGGER, CHANNEL, MESSAGE, DETAIL, THREAD_NAME) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; 201 202 private String INSERT_CHANNEL_SQL = "SYSLOG_CHANNEL (CHANNEL, CHANNEL_NAME) VALUES (?, ?)"; 203 204 private String FIND_CHANNEL_SQL_PREFIX = "SELECT CHANNEL FROM "; 205 private String FIND_CHANNEL_SQL = "SYSLOG_CHANNEL WHERE CHANNEL_NAME = ?"; 206 207 private String FIND_MAX_CHANNEL_SQL_PREFIX = "SELECT MAX(CHANNEL) FROM "; 208 private String FIND_MAX_CHANNEL_SQL = "SYSLOG_CHANNEL"; 209 210 211 214 public DatabaseLog() 215 { 216 super(); 217 218 statementAdapter = new StringDatabaseLogStatementAdapter(); 219 } 220 221 224 public void shutdown() 225 { 226 try 227 { 228 this.conn.close(); 229 } 230 catch (SQLException x) 231 { 232 } 234 } 235 236 239 public void setDriver(String driver) 240 { 241 this.driver = driver; 242 } 243 244 247 public void setTablePrefix(String tablePrefix) 248 { 249 this.tablePrefix = tablePrefix; 250 } 251 252 255 public void setURL(String url) 256 { 257 this.url = url; 258 } 259 260 263 public void setNumRetries(int retries) 264 { 265 this.numRetries = retries; 266 } 267 268 271 public void setProperties(Properties props) 272 { 273 this.props = props; 274 } 275 276 279 public void setStatementAdapter(DatabaseLogStatementAdapter adapter) 280 { 281 this.statementAdapter = adapter; 282 } 283 284 287 public DatabaseLogStatementAdapter getStatementAdapter() 288 { 289 return this.statementAdapter; 290 } 291 292 295 public String getDriver() 296 { 297 return this.driver; 298 } 299 300 303 public String getTablePrefix() 304 { 305 return this.tablePrefix; 306 } 307 308 311 public String getURL() 312 { 313 return this.url; 314 } 315 316 319 public int getNumRetries() 320 { 321 return this.numRetries; 322 } 323 324 327 public Properties getProperties() 328 { 329 return this.props; 330 } 331 332 335 public void setMessageWidth(int width) 336 { 337 this.messageWidth = width; 338 } 339 340 343 public int getMessageWidth() 344 { 345 return this.messageWidth; 346 } 347 348 351 public void setDetailWidth(int width) 352 { 353 this.detailWidth = width; 354 } 355 356 359 public int getDetailWidth() 360 { 361 return this.detailWidth; 362 } 363 364 367 public void initDatabase() 368 throws Exception 369 { 370 if (stmt != null) 371 { 372 try { stmt.close(); } catch (Exception x) { ; } 373 } 374 if (conn != null) 375 { 376 try { conn.close(); } catch (Exception x) { ; } 377 } 378 379 DatabaseUtil.registerDriver(driver); 381 382 conn = DriverManager.getConnection(url, props); 384 385 stmt = conn.prepareStatement(INSERT_PREFIX + tablePrefix + INSERT_LOG_SQL); 387 } 388 389 private synchronized int ensureChannelExists(String channel, Connection c) 390 throws Exception 391 { 392 SimpleSyslogTextFormatter format = (SimpleSyslogTextFormatter)getTextFormatter(); 393 394 String channelName = truncate(channel, format.getChannelWidth()); 395 396 Integer id = (Integer )knownChannels.get(channelName); 397 if (id != null) 398 return id.intValue(); 399 400 PreparedStatement s = null; 402 ResultSet r = null; 403 404 try 405 { 406 s = c.prepareStatement(FIND_CHANNEL_SQL_PREFIX + tablePrefix + FIND_CHANNEL_SQL); 407 s.setString(1, channelName); 408 r = s.executeQuery(); 409 if (r.next()) 410 { 411 id = new Integer (r.getInt(1)); 413 knownChannels.put(channelName, id); 414 return id.intValue(); 415 } 416 417 r.close(); 419 s.close(); 420 421 s = c.prepareStatement(FIND_MAX_CHANNEL_SQL_PREFIX + tablePrefix + FIND_MAX_CHANNEL_SQL); 423 r = s.executeQuery(); 424 int max = 0; 425 if (r.next()) 426 max = r.getInt(1); 427 r.close(); 428 s.close(); 429 430 s = c.prepareStatement(INSERT_PREFIX + tablePrefix + INSERT_CHANNEL_SQL); 432 s.setInt(1, max +1); 433 s.setString(2, channelName); 434 s.executeUpdate(); 435 436 knownChannels.put(channelName, new Integer (max +1)); 437 return (max +1); 438 } 439 finally 440 { 441 if (r != null) 443 { 444 try { r.close(); } catch (Exception x) { ; } 445 } 446 if (s != null) 447 { 448 try { s.close(); } catch (Exception x) { ; } 449 } 450 } 451 } 452 453 public final void log(SyslogMessage message) 454 { 455 log(message, 1, null); 456 } 457 458 private final void log(SyslogMessage message, int tries, Exception exception) 459 { 460 SimpleSyslogTextFormatter format = (SimpleSyslogTextFormatter)getTextFormatter(); 461 if (tries > numRetries) 462 { 463 System.err.println("############################################################"); 465 System.err.println(MessageFormat.format( 466 Syslog.getResourceString(MessageConstants.DATABASELOG_ATTEMPT_MESSAGE_1), 467 new Object [] { "DatabaseLog", String.valueOf(numRetries) })); 468 System.err.println(MessageFormat.format( 469 Syslog.getResourceString(MessageConstants.DATABASELOG_ATTEMPT_MESSAGE_2), 470 new Object [] { getName() })); 471 System.err.println(MessageFormat.format( 472 Syslog.getResourceString(MessageConstants.DATABASELOG_ATTEMPT_MESSAGE_3), 473 new Object [] { driver })); 474 System.err.println(MessageFormat.format( 475 Syslog.getResourceString(MessageConstants.DATABASELOG_ATTEMPT_MESSAGE_4), 476 new Object [] { url })); 477 System.err.println(MessageFormat.format( 478 Syslog.getResourceString(MessageConstants.DATABASELOG_ATTEMPT_MESSAGE_5), 479 new Object [] { props })); 480 if (exception != null) 481 { 482 System.err.println(""); 483 System.err.println(Syslog.getResourceString(MessageConstants.DATABASELOG_ATTEMPT_CAUSE_MESSAGE)); 484 exception.printStackTrace(); 485 } 486 System.err.println(""); 487 System.err.println(Syslog.getResourceString(MessageConstants.DATABASELOG_ORIGINAL_MESSAGE)); 488 StringBuffer buf = new StringBuffer (); 489 format.formatLogEntry(buf, message); 490 System.err.println(buf); 491 System.err.println("############################################################"); 492 return; 493 } 494 try 495 { 496 if (conn == null || stmt == null || tries > 1) 500 initDatabase(); 501 502 int chanID = ensureChannelExists(message.channel, conn); 503 String hostname = getHostname(message.host); 504 505 stmt.setTimestamp(1, new Timestamp(message.time)); 506 507 stmt.setInt(2, message.level); 508 509 stmt.setString(3, truncate(hostname, format.getHostWidth())); 510 511 stmt.setString(4, truncate(message.loggerClassname, format.getClassWidth())); 512 513 stmt.setInt(5, chanID); 514 515 stmt.setString(6, truncate(message.msg.toString(), messageWidth)); 516 517 if (message.detail == null) 518 { 519 stmt.setNull(7, Types.LONGVARCHAR); 520 } 521 else 522 { 523 StringBuffer buffer = new StringBuffer (detailWidth); 524 format.formatMessageDetail(buffer, message); 525 String messageDetail = truncate(buffer.toString(), detailWidth); 526 statementAdapter.handleLogStatement(stmt, messageDetail, 7); 527 } 528 529 stmt.setString(8, truncate(message.threadName, format.getThreadWidth())); 530 531 stmt.executeUpdate(); 532 } 533 catch (Exception x) 534 { 535 log(message, tries +1, x); 536 } 537 } 538 539 private static final String getHostname(InetAddress host) 540 { 541 return host.getHostName(); 542 } 543 544 private static final String truncate(String s, int length) 545 { 546 return (s.length() > length) ? s.substring(0, length) : s; 547 } 548 549 554 public void setTextFormatter(SyslogTextFormatter formatter) 555 { 556 if (!(formatter instanceof SimpleSyslogTextFormatter)) 557 { 558 throw new IllegalArgumentException (MessageFormat.format( 559 Syslog.getResourceString(MessageConstants.DATABASELOG_NO_TEXT_FORMATTER_MESSAGE), 560 new Object [] { "DatabaseLog", "SimpleSyslogTextFormatter" })); 561 } 562 super.setTextFormatter(formatter); 563 } 564 565 public void flush() 566 { 567 } 569 } 570 | Popular Tags |