Jump to: navigation, search

Difference between revisions of "OSEE/ReqAndDesign"

(Design)
(Design)
(30 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
== Logging ==
 
== Logging ==
 
=== Requirements ===
 
=== Requirements ===
* shall handle thousands of log entries per second
+
* shall handle creation/update of fine-grained log entries for at least 500 concurrent users
 +
* shall support logging by OSEE and other applications
 +
* the web of log entries related to an individual instance of a user request shall be able to be hierarcically related
 
* log entries shall be quickly accessible based on any combination of source, user, timestamp, log type, duration, status
 
* log entries shall be quickly accessible based on any combination of source, user, timestamp, log type, duration, status
 
* log entries shall be accessible (especially) when an application server is unresponsive
 
* log entries shall be accessible (especially) when an application server is unresponsive
 
* log entries shall be available until they are deleted by an admin or admin policy (applied by server automatically)
 
* log entries shall be available until they are deleted by an admin or admin policy (applied by server automatically)
 
* at run-time logging shall be enabled/disabled based on any combination of user, source, log level, and type
 
* at run-time logging shall be enabled/disabled based on any combination of user, source, log level, and type
* log entries related to an individual instance of a user request shall be able to be logically grouped and accessed
+
* access control shall be applied at the log entry type basis
  
 
=== Design ===
 
=== Design ===
id, parent_id, timestamp, user_id, log_level, type_id, duration, status, details (maybe in JSON format)
+
* Data
* id - random long returned for log method call
+
* Log entry in DB: entry_id, parent_id, type_id, time, duration, account_id, status, details in JSON format
* parent_id - id of entry used for grouping this and related entries.  Is negative for root entries and is the id of source of the entry client or server random id.  Ranges are used to group by client/server kind (IDE client, app server, rest client).
+
* Log entry in Java: long entryId, long parentId, long typeId, long time, long duration, long agentId, long status, String details
* timestamp - long with ms since epoch
+
** entry_id - random long returned for log method call
* user_id - long user id (artifact id of a user artifact)
+
** parent_id - id of entry used for grouping this and related entries.  Is negative for root entries and is the id of source of the entry client or server random id.  Ranges are used to group by client/server kind (IDE client, app server, rest client).
* log_level - as defined by java.util.logging.Level
+
** type_id - foreign key to type_id in osee_log_type table
* type_id - a fine-grained application defined type (might use ranges) defined as tokens with a long and name (which is not in db)
+
** time- long with ms since epoch
* duration - starts at -1 and is never updated if duration does not apply, otherwise updates when the associated job ends with duration in ms
+
** duration - starts at -1 and is never updated if duration does not apply, otherwise updates when the associated job ends with duration in ms
* Status:
+
** account_id - long account id (the account_id returned from account management services
   0-99   percent complete
+
** Status:
   200 OK  completed normally
+
   0     initial value
   4xx    client error (as defined for HTTP Status Code Definitions)
+
  1-99 percent complete
   500    server error (as defined for HTTP Status Code Definitions)
+
   100  completed normally
 +
   101  completed abnormally
 +
* Each new log entry's parent_id, agent_id is mapped to the thread that created it (only the most recent mapping per thread is maintained)
 +
When an exception is thrown, it is logged as a child of the parent corresponding to the current thread.  If no mapping is found    
 +
ConcurrentHashMap<Thread, Pair<Long, Long>>()
  
* server uses a queue to collect log entries for a short time (configurable) and then inserts them in batch. This means that any update to a log entry that occurs in less than this configured time will not require a database update (i.e. writing the duration of a short operation). This also means only one thread writes to the log table per server.
+
* Log entry type in DB: type_id, log_level, software_unit, message_format
 +
** type_id - a fine-grained application defined type, random id, defined as tokens and stored in the db for cross application support
 +
** log_level - as defined by java.util.logging.Level
 +
** software_unit - application defined name of the software unit that uses this log entry type
 +
** message_format - format defined by [http://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html java.util.Formatter]
  
  [http://www.precisejava.com/javaperf/j2ee/JDBC.htm Optimize JDBC Performance]
+
* high performance
 +
** 2 ConcurrentHashMap are allocated with an initial configurable size: newLogEntires, updatedEntries
 +
** newly created log entries are added to newLogEntires using the entry_id as the key and the array of sql insert parameters as the value
 +
** updated log entries are checked for in newLogEntires and updated if they exist, otherwise the update map is checked and updated if exists, else added to updatedEntries
 +
** A timer tasks runs at a configurable (short) periodic rate and batch inserts the log entires in the insert map and then runs the updates. This means that any update to a log entry that occurs in less than this configured time will not require a database update (i.e. writing the duration of a short operation).  This also means only one thread writes to the log table per JVM.
 +
** new DrainingIterator(newLogEntires.values().iterator()) is used to iterate through the values and remove them one at a time during the batch insert
 +
** upon server shutdown must flush log
 +
** IDE client will directly use the same service that is used on the server
 +
** [http://stackoverflow.com/questions/8203864/the-best-concurrency-list-in-java data structure options]
 +
** [http://www.precisejava.com/javaperf/j2ee/JDBC.htm Optimize JDBC Performance]
  
== Exception Handeling ==
+
 
 +
<source lang="java">
 +
Long createThreadEntry(long userId, Long typeId);
 +
 
 +
Long createThreadEntry(long userId, Long typeId, long parentId);
 +
 
 +
Long createEntry(Long typeId, Object... messageArgs);
 +
 
 +
Long createEntry(Long typeId, Long parentId, Object... messageArgs);
 +
 
 +
void updateEntry(Long entryId, Long status);
 +
 
 +
Long createExceptionEntry(Throwable throwable);
 +
 
 +
</source>
 +
 
 +
* The first interface to the logging data can be the basic REST navigation
 +
 
 +
== Exception Handling ==
 
=== Requirements ===
 
=== Requirements ===
 
* avoid unnecessary wrapping of exceptions
 
* avoid unnecessary wrapping of exceptions

Revision as of 16:23, 20 November 2013

Logging

Requirements

  • shall handle creation/update of fine-grained log entries for at least 500 concurrent users
  • shall support logging by OSEE and other applications
  • the web of log entries related to an individual instance of a user request shall be able to be hierarcically related
  • log entries shall be quickly accessible based on any combination of source, user, timestamp, log type, duration, status
  • log entries shall be accessible (especially) when an application server is unresponsive
  • log entries shall be available until they are deleted by an admin or admin policy (applied by server automatically)
  • at run-time logging shall be enabled/disabled based on any combination of user, source, log level, and type
  • access control shall be applied at the log entry type basis

Design

  • Data
  • Log entry in DB: entry_id, parent_id, type_id, time, duration, account_id, status, details in JSON format
  • Log entry in Java: long entryId, long parentId, long typeId, long time, long duration, long agentId, long status, String details
    • entry_id - random long returned for log method call
    • parent_id - id of entry used for grouping this and related entries. Is negative for root entries and is the id of source of the entry client or server random id. Ranges are used to group by client/server kind (IDE client, app server, rest client).
    • type_id - foreign key to type_id in osee_log_type table
    • time- long with ms since epoch
    • duration - starts at -1 and is never updated if duration does not apply, otherwise updates when the associated job ends with duration in ms
    • account_id - long account id (the account_id returned from account management services
    • Status:
 0     initial value
 1-99  percent complete
 100   completed normally
 101   completed abnormally
  • Each new log entry's parent_id, agent_id is mapped to the thread that created it (only the most recent mapping per thread is maintained)

When an exception is thrown, it is logged as a child of the parent corresponding to the current thread. If no mapping is found ConcurrentHashMap<Thread, Pair<Long, Long>>()

  • Log entry type in DB: type_id, log_level, software_unit, message_format
    • type_id - a fine-grained application defined type, random id, defined as tokens and stored in the db for cross application support
    • log_level - as defined by java.util.logging.Level
    • software_unit - application defined name of the software unit that uses this log entry type
    • message_format - format defined by java.util.Formatter
  • high performance
    • 2 ConcurrentHashMap are allocated with an initial configurable size: newLogEntires, updatedEntries
    • newly created log entries are added to newLogEntires using the entry_id as the key and the array of sql insert parameters as the value
    • updated log entries are checked for in newLogEntires and updated if they exist, otherwise the update map is checked and updated if exists, else added to updatedEntries
    • A timer tasks runs at a configurable (short) periodic rate and batch inserts the log entires in the insert map and then runs the updates. This means that any update to a log entry that occurs in less than this configured time will not require a database update (i.e. writing the duration of a short operation). This also means only one thread writes to the log table per JVM.
    • new DrainingIterator(newLogEntires.values().iterator()) is used to iterate through the values and remove them one at a time during the batch insert
    • upon server shutdown must flush log
    • IDE client will directly use the same service that is used on the server
    • data structure options
    • Optimize JDBC Performance


 Long createThreadEntry(long userId, Long typeId);
 
 Long createThreadEntry(long userId, Long typeId, long parentId);
 
 Long createEntry(Long typeId, Object... messageArgs);
 
 Long createEntry(Long typeId, Long parentId, Object... messageArgs);
 
 void updateEntry(Long entryId, Long status);
 
 Long createExceptionEntry(Throwable throwable);
  • The first interface to the logging data can be the basic REST navigation

Exception Handling

Requirements

  • avoid unnecessary wrapping of exceptions

Design

Checked exceptions I love you, but you have to go Why should you use Unchecked exceptions over Checked exceptions Clean Code by Example: Checked versus unchecked exceptions

  • Use application specific exceptions that extend RuntimeException - application specific allows for setting exception breakpoints in the debugger
  • Do not declare any run-time exceptions in any method signatures