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 org.apache.commons.logging.Log;
   24   import org.apache.commons.logging.LogFactory;
   25   import org.quartz.JobExecutionContext;
   26   import org.quartz.JobExecutionException;
   27   import org.quartz.Scheduler;
   28   import org.quartz.SchedulerException;
   29   import org.quartz.Trigger;
   30   import org.quartz.JobListener;
   31   import org.quartz.spi.SchedulerPlugin;
   32   
   33   import java.text.MessageFormat;
   34   
   35   /**
   36    * Logs a history of all job executions (and execution vetos) via the 
   37    * Jakarta Commons-Logging framework.
   38    * 
   39    * <p>
   40    * The logged message is customizable by setting one of the following message
   41    * properties to a String that conforms to the syntax of <code>java.util.MessageFormat</code>.
   42    * </p>
   43    * 
   44    * <p>
   45    * JobToBeFiredMessage - available message data are: <table>
   46    * <tr>
   47    * <th>Element</th>
   48    * <th>Data Type</th>
   49    * <th>Description</th>
   50    * </tr>
   51    * <tr>
   52    * <td>0</td>
   53    * <td>String</td>
   54    * <td>The Job's Name.</td>
   55    * </tr>
   56    * <tr>
   57    * <td>1</td>
   58    * <td>String</td>
   59    * <td>The Job's Group.</td>
   60    * </tr>
   61    * <tr>
   62    * <td>2</td>
   63    * <td>Date</td>
   64    * <td>The current time.</td>
   65    * </tr>
   66    * <tr>
   67    * <td>3</td>
   68    * <td>String</td>
   69    * <td>The Trigger's name.</td>
   70    * </tr>
   71    * <tr>
   72    * <td>4</td>
   73    * <td>String</td>
   74    * <td>The Triggers's group.</td>
   75    * </tr>
   76    * <tr>
   77    * <td>5</td>
   78    * <td>Date</td>
   79    * <td>The scheduled fire time.</td>
   80    * </tr>
   81    * <tr>
   82    * <td>6</td>
   83    * <td>Date</td>
   84    * <td>The next scheduled fire time.</td>
   85    * </tr>
   86    * <tr>
   87    * <td>7</td>
   88    * <td>Integer</td>
   89    * <td>The re-fire count from the JobExecutionContext.</td>
   90    * </tr>
   91    * </table>
   92    * 
   93    * The default message text is <i>"Job {1}.{0} fired (by trigger {4}.{3}) at:
   94    * {2, date, HH:mm:ss MM/dd/yyyy}"</i>
   95    * </p>
   96    * 
   97    * 
   98    * <p>
   99    * JobSuccessMessage - available message data are: <table>
  100    * <tr>
  101    * <th>Element</th>
  102    * <th>Data Type</th>
  103    * <th>Description</th>
  104    * </tr>
  105    * <tr>
  106    * <td>0</td>
  107    * <td>String</td>
  108    * <td>The Job's Name.</td>
  109    * </tr>
  110    * <tr>
  111    * <td>1</td>
  112    * <td>String</td>
  113    * <td>The Job's Group.</td>
  114    * </tr>
  115    * <tr>
  116    * <td>2</td>
  117    * <td>Date</td>
  118    * <td>The current time.</td>
  119    * </tr>
  120    * <tr>
  121    * <td>3</td>
  122    * <td>String</td>
  123    * <td>The Trigger's name.</td>
  124    * </tr>
  125    * <tr>
  126    * <td>4</td>
  127    * <td>String</td>
  128    * <td>The Triggers's group.</td>
  129    * </tr>
  130    * <tr>
  131    * <td>5</td>
  132    * <td>Date</td>
  133    * <td>The scheduled fire time.</td>
  134    * </tr>
  135    * <tr>
  136    * <td>6</td>
  137    * <td>Date</td>
  138    * <td>The next scheduled fire time.</td>
  139    * </tr>
  140    * <tr>
  141    * <td>7</td>
  142    * <td>Integer</td>
  143    * <td>The re-fire count from the JobExecutionContext.</td>
  144    * </tr>
  145    * <tr>
  146    * <td>8</td>
  147    * <td>Object</td>
  148    * <td>The string value (toString() having been called) of the result (if any) 
  149    *      that the Job set on the JobExecutionContext, with on it.  "NULL" if no 
  150    *      result was set.</td>
  151    * </td>
  152    * </tr>
  153    * </table>
  154    * 
  155    * The default message text is <i>"Job {1}.{0} execution complete at {2, date,
  156    * HH:mm:ss MM/dd/yyyy} and reports: {8}"</i>
  157    * </p>
  158    * 
  159    * <p>
  160    * JobFailedMessage - available message data are: <table>
  161    * <tr>
  162    * <th>Element</th>
  163    * <th>Data Type</th>
  164    * <th>Description</th>
  165    * </tr>
  166    * <tr>
  167    * <td>0</td>
  168    * <td>String</td>
  169    * <td>The Job's Name.</td>
  170    * </tr>
  171    * <tr>
  172    * <td>1</td>
  173    * <td>String</td>
  174    * <td>The Job's Group.</td>
  175    * </tr>
  176    * <tr>
  177    * <td>2</td>
  178    * <td>Date</td>
  179    * <td>The current time.</td>
  180    * </tr>
  181    * <tr>
  182    * <td>3</td>
  183    * <td>String</td>
  184    * <td>The Trigger's name.</td>
  185    * </tr>
  186    * <tr>
  187    * <td>4</td>
  188    * <td>String</td>
  189    * <td>The Triggers's group.</td>
  190    * </tr>
  191    * <tr>
  192    * <td>5</td>
  193    * <td>Date</td>
  194    * <td>The scheduled fire time.</td>
  195    * </tr>
  196    * <tr>
  197    * <td>6</td>
  198    * <td>Date</td>
  199    * <td>The next scheduled fire time.</td>
  200    * </tr>
  201    * <tr>
  202    * <td>7</td>
  203    * <td>Integer</td>
  204    * <td>The re-fire count from the JobExecutionContext.</td>
  205    * </tr>
  206    * <tr>
  207    * <td>8</td>
  208    * <td>String</td>
  209    * <td>The message from the thrown JobExecution Exception.
  210    * </td>
  211    * </tr>
  212    * </table>
  213    * 
  214    * The default message text is <i>"Job {1}.{0} execution failed at {2, date,
  215    * HH:mm:ss MM/dd/yyyy} and reports: {8}"</i>
  216    * </p>
  217    * 
  218    * 
  219    * <p>
  220    * JobWasVetoedMessage - available message data are: <table>
  221    * <tr>
  222    * <th>Element</th>
  223    * <th>Data Type</th>
  224    * <th>Description</th>
  225    * </tr>
  226    * <tr>
  227    * <td>0</td>
  228    * <td>String</td>
  229    * <td>The Job's Name.</td>
  230    * </tr>
  231    * <tr>
  232    * <td>1</td>
  233    * <td>String</td>
  234    * <td>The Job's Group.</td>
  235    * </tr>
  236    * <tr>
  237    * <td>2</td>
  238    * <td>Date</td>
  239    * <td>The current time.</td>
  240    * </tr>
  241    * <tr>
  242    * <td>3</td>
  243    * <td>String</td>
  244    * <td>The Trigger's name.</td>
  245    * </tr>
  246    * <tr>
  247    * <td>4</td>
  248    * <td>String</td>
  249    * <td>The Triggers's group.</td>
  250    * </tr>
  251    * <tr>
  252    * <td>5</td>
  253    * <td>Date</td>
  254    * <td>The scheduled fire time.</td>
  255    * </tr>
  256    * <tr>
  257    * <td>6</td>
  258    * <td>Date</td>
  259    * <td>The next scheduled fire time.</td>
  260    * </tr>
  261    * <tr>
  262    * <td>7</td>
  263    * <td>Integer</td>
  264    * <td>The re-fire count from the JobExecutionContext.</td>
  265    * </tr>
  266    * </table>
  267    * 
  268    * The default message text is <i>"Job {1}.{0} was vetoed.  It was to be fired 
  269    * (by trigger {4}.{3}) at: {2, date, HH:mm:ss MM/dd/yyyy}"</i>
  270    * </p>
  271    * 
  272    * 
  273    * @author James House
  274    */
  275   public class LoggingJobHistoryPlugin implements SchedulerPlugin, JobListener {
  276   
  277       /*
  278        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  279        * 
  280        * Data members.
  281        * 
  282        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  283        */
  284   
  285       private String name;
  286   
  287       private String jobToBeFiredMessage = "Job {1}.{0} fired (by trigger {4}.{3}) at: {2, date, HH:mm:ss MM/dd/yyyy}";
  288       
  289       private String jobSuccessMessage = "Job {1}.{0} execution complete at {2, date, HH:mm:ss MM/dd/yyyy} and reports: {8}";
  290   
  291       private String jobFailedMessage = "Job {1}.{0} execution failed at {2, date, HH:mm:ss MM/dd/yyyy} and reports: {8}";
  292   
  293       private String jobWasVetoedMessage = "Job {1}.{0} was vetoed.  It was to be fired (by trigger {4}.{3}) at: {2, date, HH:mm:ss MM/dd/yyyy}";
  294   
  295       private final Log log = LogFactory.getLog(getClass());
  296   
  297       /*
  298        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  299        * 
  300        * Constructors.
  301        * 
  302        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  303        */
  304   
  305       public LoggingJobHistoryPlugin() {
  306       }
  307   
  308       /*
  309        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  310        * 
  311        * Interface.
  312        * 
  313        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  314        */
  315   
  316       protected Log getLog() {
  317           return log;
  318       }
  319   
  320       /**
  321        * Get the message that is logged when a Job successfully completes its 
  322        * execution.
  323        */
  324       public String getJobSuccessMessage() {
  325           return jobSuccessMessage;
  326       }
  327   
  328       /**
  329        * Get the message that is logged when a Job fails its 
  330        * execution.
  331        */
  332       public String getJobFailedMessage() {
  333           return jobFailedMessage;
  334       }
  335   
  336       /**
  337        * Get the message that is logged when a Job is about to execute.
  338        */
  339       public String getJobToBeFiredMessage() {
  340           return jobToBeFiredMessage;
  341       }
  342   
  343       /**
  344        * Set the message that is logged when a Job successfully completes its 
  345        * execution.
  346        * 
  347        * @param jobSuccessMessage
  348        *          String in java.text.MessageFormat syntax.
  349        */
  350       public void setJobSuccessMessage(String jobSuccessMessage) {
  351           this.jobSuccessMessage = jobSuccessMessage;
  352       }
  353   
  354       /**
  355        * Set the message that is logged when a Job fails its 
  356        * execution.
  357        * 
  358        * @param jobFailedMessage
  359        *          String in java.text.MessageFormat syntax.
  360        */
  361       public void setJobFailedMessage(String jobFailedMessage) {
  362           this.jobFailedMessage = jobFailedMessage;
  363       }
  364   
  365       /**
  366        * Set the message that is logged when a Job is about to execute.
  367        * 
  368        * @param jobToBeFiredMessage
  369        *          String in java.text.MessageFormat syntax.
  370        */
  371       public void setJobToBeFiredMessage(String jobToBeFiredMessage) {
  372           this.jobToBeFiredMessage = jobToBeFiredMessage;
  373       }
  374   
  375       /**
  376        * Get the message that is logged when a Job execution is vetoed by a
  377        * trigger listener.
  378        */
  379       public String getJobWasVetoedMessage() {
  380           return jobWasVetoedMessage;
  381       }
  382   
  383       /**
  384        * Set the message that is logged when a Job execution is vetoed by a
  385        * trigger listener.
  386        * 
  387        * @param jobWasVetoedMessage
  388        *          String in java.text.MessageFormat syntax.
  389        */
  390       public void setJobWasVetoedMessage(String jobWasVetoedMessage) {
  391           this.jobWasVetoedMessage = jobWasVetoedMessage;
  392       }
  393   
  394       /*
  395        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  396        * 
  397        * SchedulerPlugin Interface.
  398        * 
  399        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  400        */
  401   
  402       /**
  403        * <p>
  404        * Called during creation of the <code>Scheduler</code> in order to give
  405        * the <code>SchedulerPlugin</code> a chance to initialize.
  406        * </p>
  407        * 
  408        * @throws SchedulerConfigException
  409        *           if there is an error initializing.
  410        */
  411       public void initialize(String name, Scheduler scheduler)
  412           throws SchedulerException {
  413           this.name = name;
  414           scheduler.addGlobalJobListener(this);
  415       }
  416   
  417       public void start() {
  418           // do nothing...
  419       }
  420   
  421       /**
  422        * <p>
  423        * Called in order to inform the <code>SchedulerPlugin</code> that it
  424        * should free up all of it's resources because the scheduler is shutting
  425        * down.
  426        * </p>
  427        */
  428       public void shutdown() {
  429           // nothing to do...
  430       }
  431   
  432       /*
  433        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  434        * 
  435        * JobListener Interface.
  436        * 
  437        * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  438        */
  439   
  440       /*
  441        * Object[] arguments = { new Integer(7), new
  442        * Date(System.currentTimeMillis()), "a disturbance in the Force" };
  443        * 
  444        * String result = MessageFormat.format( "At {1,time} on {1,date}, there
  445        * was {2} on planet {0,number,integer}.", arguments);
  446        */
  447   
  448       public String getName() {
  449           return name;
  450       }
  451   
  452       /** 
  453        * @see org.quartz.JobListener#jobToBeExecuted(JobExecutionContext)
  454        */
  455       public void jobToBeExecuted(JobExecutionContext context) {
  456           if (!getLog().isInfoEnabled()) {
  457               return;
  458           } 
  459           
  460           Trigger trigger = context.getTrigger();
  461   
  462           Object[] args = {
  463               context.getJobDetail().getName(),
  464               context.getJobDetail().getGroup(), new java.util.Date(),
  465               trigger.getName(), trigger.getGroup(),
  466               trigger.getPreviousFireTime(), trigger.getNextFireTime(),
  467               new Integer(context.getRefireCount())
  468           };
  469   
  470           getLog().info(MessageFormat.format(getJobToBeFiredMessage(), args));
  471       }
  472       
  473       /** 
  474        * @see org.quartz.JobListener#jobWasExecuted(JobExecutionContext, JobExecutionException)
  475        */
  476       public void jobWasExecuted(JobExecutionContext context,
  477               JobExecutionException jobException) {
  478   
  479           Trigger trigger = context.getTrigger();
  480           
  481           Object[] args = null;
  482           
  483           if (jobException != null) {
  484               if (!getLog().isWarnEnabled()) {
  485                   return;
  486               } 
  487               
  488               String errMsg = jobException.getMessage();
  489               args = 
  490                   new Object[] {
  491                       context.getJobDetail().getName(),
  492                       context.getJobDetail().getGroup(), new java.util.Date(),
  493                       trigger.getName(), trigger.getGroup(),
  494                       trigger.getPreviousFireTime(), trigger.getNextFireTime(),
  495                       new Integer(context.getRefireCount()), errMsg
  496                   };
  497               
  498               getLog().warn(MessageFormat.format(getJobFailedMessage(), args), jobException); 
  499           } else {
  500               if (!getLog().isInfoEnabled()) {
  501                   return;
  502               } 
  503               
  504               String result = String.valueOf(context.getResult());
  505               args =
  506                   new Object[] {
  507                       context.getJobDetail().getName(),
  508                       context.getJobDetail().getGroup(), new java.util.Date(),
  509                       trigger.getName(), trigger.getGroup(),
  510                       trigger.getPreviousFireTime(), trigger.getNextFireTime(),
  511                       new Integer(context.getRefireCount()), result
  512                   };
  513               
  514               getLog().info(MessageFormat.format(getJobSuccessMessage(), args));
  515           }
  516       }
  517   
  518       /** 
  519        * @see org.quartz.JobListener#jobExecutionVetoed(org.quartz.JobExecutionContext)
  520        */
  521       public void jobExecutionVetoed(JobExecutionContext context) {
  522           
  523           if (!getLog().isInfoEnabled()) {
  524               return;
  525           } 
  526           
  527           Trigger trigger = context.getTrigger();
  528   
  529           Object[] args = {
  530               context.getJobDetail().getName(),
  531               context.getJobDetail().getGroup(), new java.util.Date(),
  532               trigger.getName(), trigger.getGroup(),
  533               trigger.getPreviousFireTime(), trigger.getNextFireTime(),
  534               new Integer(context.getRefireCount())
  535           };
  536   
  537           getLog().info(MessageFormat.format(getJobWasVetoedMessage(), args));
  538       }
  539   
  540   }
  541   
  542   // EOF

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