Save This Page
Home » quartz-1.6.0 » org » quartz » plugins » history » [javadoc | source]
    1   /* 
    2    * Copyright 2004-2005 OpenSymphony 
    3    * 
    4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
    5    * use this file except in compliance with the License. You may obtain a copy 
    6    * of the License at 
    7    * 
    8    *   http://www.apache.org/licenses/LICENSE-2.0 
    9    *   
   10    * Unless required by applicable law or agreed to in writing, software 
   11    * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
   12    * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
   13    * License for the specific language governing permissions and limitations 
   14    * under the License.
   15    * 
   16    */
   17   
   18   /*
   19    * Previously Copyright (c) 2001-2004 James House
   20    */
   21   package org.quartz.plugins.history;
   22   
   23   import java.text.MessageFormat;
   24   
   25   import org.apache.commons.logging.Log;
   26   import org.apache.commons.logging.LogFactory;
   27   import org.quartz.JobExecutionContext;
   28   import org.quartz.Scheduler;
   29   import org.quartz.SchedulerException;
   30   import org.quartz.Trigger;
   31   import org.quartz.TriggerListener;
   32   import org.quartz.spi.SchedulerPlugin;
   33   
   34   /**
   35    * Logs a history of all trigger firings via the Jakarta Commons-Logging
   36    * framework.
   37    * 
   38    * <p>
   39    * The logged message is customizable by setting one of the following message
   40    * properties to a String that conforms to the syntax of <code>java.util.MessageFormat</code>.
   41    * </p>
   42    * 
   43    * <p>
   44    * TriggerFiredMessage - available message data are: <table>
   45    * <tr>
   46    * <th>Element</th>
   47    * <th>Data Type</th>
   48    * <th>Description</th>
   49    * </tr>
   50    * <tr>
   51    * <td>0</td>
   52    * <td>String</td>
   53    * <td>The Trigger's Name.</td>
   54    * </tr>
   55    * <tr>
   56    * <td>1</td>
   57    * <td>String</td>
   58    * <td>The Trigger's Group.</td>
   59    * </tr>
   60    * <tr>
   61    * <td>2</td>
   62    * <td>Date</td>
   63    * <td>The scheduled fire time.</td>
   64    * </tr>
   65    * <tr>
   66    * <td>3</td>
   67    * <td>Date</td>
   68    * <td>The next scheduled fire time.</td>
   69    * </tr>
   70    * <tr>
   71    * <td>4</td>
   72    * <td>Date</td>
   73    * <td>The actual fire time.</td>
   74    * </tr>
   75    * <tr>
   76    * <td>5</td>
   77    * <td>String</td>
   78    * <td>The Job's name.</td>
   79    * </tr>
   80    * <tr>
   81    * <td>6</td>
   82    * <td>String</td>
   83    * <td>The Job's group.</td>
   84    * </tr>
   85    * <tr>
   86    * <td>7</td>
   87    * <td>Integer</td>
   88    * <td>The re-fire count from the JobExecutionContext.</td>
   89    * </tr>
   90    * </table>
   91    * 
   92    * The default message text is <i>"Trigger {1}.{0} fired job {6}.{5} at: {4,
   93    * date, HH:mm:ss MM/dd/yyyy}"</i>
   94    * </p>
   95    * 
   96    * <p>
   97    * TriggerMisfiredMessage - available message data are: <table>
   98    * <tr>
   99    * <th>Element</th>
  100    * <th>Data Type</th>
  101    * <th>Description</th>
  102    * </tr>
  103    * <tr>
  104    * <td>0</td>
  105    * <td>String</td>
  106    * <td>The Trigger's Name.</td>
  107    * </tr>
  108    * <tr>
  109    * <td>1</td>
  110    * <td>String</td>
  111    * <td>The Trigger's Group.</td>
  112    * </tr>
  113    * <tr>
  114    * <td>2</td>
  115    * <td>Date</td>
  116    * <td>The scheduled fire time.</td>
  117    * </tr>
  118    * <tr>
  119    * <td>3</td>
  120    * <td>Date</td>
  121    * <td>The next scheduled fire time.</td>
  122    * </tr>
  123    * <tr>
  124    * <td>4</td>
  125    * <td>Date</td>
  126    * <td>The actual fire time. (the time the misfire was detected/handled)</td>
  127    * </tr>
  128    * <tr>
  129    * <td>5</td>
  130    * <td>String</td>
  131    * <td>The Job's name.</td>
  132    * </tr>
  133    * <tr>
  134    * <td>6</td>
  135    * <td>String</td>
  136    * <td>The Job's group.</td>
  137    * </tr>
  138    * </table>
  139    * 
  140    * The default message text is <i>"Trigger {1}.{0} misfired job {6}.{5} at:
  141    * {4, date, HH:mm:ss MM/dd/yyyy}. Should have fired at: {3, date, HH:mm:ss
  142    * MM/dd/yyyy}"</i>
  143    * </p>
  144    * 
  145    * <p>
  146    * TriggerCompleteMessage - available message data are: <table>
  147    * <tr>
  148    * <th>Element</th>
  149    * <th>Data Type</th>
  150    * <th>Description</th>
  151    * </tr>
  152    * <tr>
  153    * <td>0</td>
  154    * <td>String</td>
  155    * <td>The Trigger's Name.</td>
  156    * </tr>
  157    * <tr>
  158    * <td>1</td>
  159    * <td>String</td>
  160    * <td>The Trigger's Group.</td>
  161    * </tr>
  162    * <tr>
  163    * <td>2</td>
  164    * <td>Date</td>
  165    * <td>The scheduled fire time.</td>
  166    * </tr>
  167    * <tr>
  168    * <td>3</td>
  169    * <td>Date</td>
  170    * <td>The next scheduled fire time.</td>
  171    * </tr>
  172    * <tr>
  173    * <td>4</td>
  174    * <td>Date</td>
  175    * <td>The job completion time.</td>
  176    * </tr>
  177    * <tr>
  178    * <td>5</td>
  179    * <td>String</td>
  180    * <td>The Job's name.</td>
  181    * </tr>
  182    * <tr>
  183    * <td>6</td>
  184    * <td>String</td>
  185    * <td>The Job's group.</td>
  186    * </tr>
  187    * <tr>
  188    * <td>7</td>
  189    * <td>Integer</td>
  190    * <td>The re-fire count from the JobExecutionContext.</td>
  191    * </tr>
  192    * <tr>
  193    * <td>8</td>
  194    * <td>Integer</td>
  195    * <td>The trigger's resulting instruction code.</td>
  196    * </tr>
  197    * <tr>
  198    * <td>9</td>
  199    * <td>String</td>
  200    * <td>A human-readable translation of the trigger's resulting instruction
  201    * code.</td>
  202    * </tr>
  203    * </table>
  204    * 
  205    * The default message text is <i>"Trigger {1}.{0} completed firing job
  206    * {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} with resulting trigger instruction
  207    * code: {9}"</i>
  208    * </p>
  209    * 
  210    * @author James House
  211    */
  212   public class LoggingTriggerHistoryPlugin implements SchedulerPlugin,
  213           TriggerListener {
  214   
  215       /*
  216        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  217        * 
  218        * Data members.
  219        * 
  220        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  221        */
  222   
  223       private String name;
  224   
  225       private String triggerFiredMessage = "Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss MM/dd/yyyy}";
  226   
  227       private String triggerMisfiredMessage = "Trigger {1}.{0} misfired job {6}.{5}  at: {4, date, HH:mm:ss MM/dd/yyyy}.  Should have fired at: {3, date, HH:mm:ss MM/dd/yyyy}";
  228   
  229       private String triggerCompleteMessage = "Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} with resulting trigger instruction code: {9}";
  230   
  231       private final Log log = LogFactory.getLog(getClass());
  232   
  233       /*
  234        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  235        * 
  236        * Constructors.
  237        * 
  238        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  239        */
  240   
  241       public LoggingTriggerHistoryPlugin() {
  242       }
  243   
  244       /*
  245        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  246        * 
  247        * Interface.
  248        * 
  249        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  250        */
  251   
  252       protected Log getLog() {
  253           return log;
  254       }
  255   
  256       /**
  257        * Get the message that is printed upon the completion of a trigger's
  258        * firing.
  259        * 
  260        * @return String
  261        */
  262       public String getTriggerCompleteMessage() {
  263           return triggerCompleteMessage;
  264       }
  265   
  266       /**
  267        * Get the message that is printed upon a trigger's firing.
  268        * 
  269        * @return String
  270        */
  271       public String getTriggerFiredMessage() {
  272           return triggerFiredMessage;
  273       }
  274   
  275       /**
  276        * Get the message that is printed upon a trigger's mis-firing.
  277        * 
  278        * @return String
  279        */
  280       public String getTriggerMisfiredMessage() {
  281           return triggerMisfiredMessage;
  282       }
  283   
  284       /**
  285        * Set the message that is printed upon the completion of a trigger's
  286        * firing.
  287        * 
  288        * @param triggerCompleteMessage
  289        *          String in java.text.MessageFormat syntax.
  290        */
  291       public void setTriggerCompleteMessage(String triggerCompleteMessage) {
  292           this.triggerCompleteMessage = triggerCompleteMessage;
  293       }
  294   
  295       /**
  296        * Set the message that is printed upon a trigger's firing.
  297        * 
  298        * @param triggerFiredMessage
  299        *          String in java.text.MessageFormat syntax.
  300        */
  301       public void setTriggerFiredMessage(String triggerFiredMessage) {
  302           this.triggerFiredMessage = triggerFiredMessage;
  303       }
  304   
  305       /**
  306        * Set the message that is printed upon a trigger's firing.
  307        * 
  308        * @param triggerMisfiredMessage
  309        *          String in java.text.MessageFormat syntax.
  310        */
  311       public void setTriggerMisfiredMessage(String triggerMisfiredMessage) {
  312           this.triggerMisfiredMessage = triggerMisfiredMessage;
  313       }
  314   
  315       /*
  316        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  317        * 
  318        * SchedulerPlugin Interface.
  319        * 
  320        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  321        */
  322   
  323       /**
  324        * <p>
  325        * Called during creation of the <code>Scheduler</code> in order to give
  326        * the <code>SchedulerPlugin</code> a chance to initialize.
  327        * </p>
  328        * 
  329        * @throws SchedulerConfigException
  330        *           if there is an error initializing.
  331        */
  332       public void initialize(String name, Scheduler scheduler)
  333           throws SchedulerException {
  334           this.name = name;
  335   
  336           scheduler.addGlobalTriggerListener(this);
  337       }
  338   
  339       public void start() {
  340           // do nothing...
  341       }
  342   
  343       /**
  344        * <p>
  345        * Called in order to inform the <code>SchedulerPlugin</code> that it
  346        * should free up all of it's resources because the scheduler is shutting
  347        * down.
  348        * </p>
  349        */
  350       public void shutdown() {
  351           // nothing to do...
  352       }
  353   
  354       /*
  355        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  356        * 
  357        * TriggerListener Interface.
  358        * 
  359        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  360        */
  361   
  362       /*
  363        * Object[] arguments = { new Integer(7), new
  364        * Date(System.currentTimeMillis()), "a disturbance in the Force" };
  365        * 
  366        * String result = MessageFormat.format( "At {1,time} on {1,date}, there
  367        * was {2} on planet {0,number,integer}.", arguments);
  368        */
  369   
  370       public String getName() {
  371           return name;
  372       }
  373   
  374       public void triggerFired(Trigger trigger, JobExecutionContext context) {
  375           if (!getLog().isInfoEnabled()) {
  376               return;
  377           } 
  378           
  379           Object[] args = {
  380               trigger.getName(), trigger.getGroup(),
  381               trigger.getPreviousFireTime(), trigger.getNextFireTime(),
  382               new java.util.Date(), context.getJobDetail().getName(),
  383               context.getJobDetail().getGroup(),
  384               new Integer(context.getRefireCount())
  385           };
  386   
  387           getLog().info(MessageFormat.format(getTriggerFiredMessage(), args));
  388       }
  389   
  390       public void triggerMisfired(Trigger trigger) {
  391           if (!getLog().isInfoEnabled()) {
  392               return;
  393           } 
  394           
  395           Object[] args = {
  396               trigger.getName(), trigger.getGroup(),
  397               trigger.getPreviousFireTime(), trigger.getNextFireTime(),
  398               new java.util.Date(), trigger.getJobGroup(),
  399               trigger.getJobGroup()
  400           };
  401   
  402           getLog().info(MessageFormat.format(getTriggerMisfiredMessage(), args));
  403       }
  404   
  405       public void triggerComplete(Trigger trigger, JobExecutionContext context,
  406               int triggerInstructionCode) {
  407           if (!getLog().isInfoEnabled()) {
  408               return;
  409           } 
  410           
  411           String instrCode = "UNKNOWN";
  412           if (triggerInstructionCode == Trigger.INSTRUCTION_DELETE_TRIGGER) {
  413               instrCode = "DELETE TRIGGER";
  414           } else if (triggerInstructionCode == Trigger.INSTRUCTION_NOOP) {
  415               instrCode = "DO NOTHING";
  416           } else if (triggerInstructionCode == Trigger.INSTRUCTION_RE_EXECUTE_JOB) {
  417               instrCode = "RE-EXECUTE JOB";
  418           } else if (triggerInstructionCode == Trigger.INSTRUCTION_SET_ALL_JOB_TRIGGERS_COMPLETE) {
  419               instrCode = "SET ALL OF JOB'S TRIGGERS COMPLETE";
  420           } else if (triggerInstructionCode == Trigger.INSTRUCTION_SET_TRIGGER_COMPLETE) {
  421               instrCode = "SET THIS TRIGGER COMPLETE";
  422           }
  423   
  424           Object[] args = {
  425               trigger.getName(), trigger.getGroup(),
  426               trigger.getPreviousFireTime(), trigger.getNextFireTime(),
  427               new java.util.Date(), context.getJobDetail().getName(),
  428               context.getJobDetail().getGroup(),
  429               new Integer(context.getRefireCount()),
  430               new Integer(triggerInstructionCode), instrCode
  431           };
  432   
  433           getLog().info(MessageFormat.format(getTriggerCompleteMessage(), args));
  434       }
  435   
  436       public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
  437           return false;
  438       }
  439   
  440   }

Save This Page
Home » quartz-1.6.0 » org » quartz » plugins » history » [javadoc | source]