001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.server.monitors;
028
029import static org.opends.server.core.DirectoryServer.*;
030
031import java.util.ArrayList;
032import java.util.concurrent.TimeUnit;
033
034import org.forgerock.opendj.config.server.ConfigException;
035import org.opends.server.admin.std.server.MonitorProviderCfg;
036import org.opends.server.api.MonitorProvider;
037import org.opends.server.extensions.ParallelWorkQueue;
038import org.opends.server.types.Attribute;
039import org.opends.server.types.AttributeType;
040import org.opends.server.types.Attributes;
041import org.opends.server.types.InitializationException;
042
043/**
044 * This class defines a Directory Server monitor that can be used to provide
045 * information about the state of the work queue.
046 */
047public class ParallelWorkQueueMonitor
048       extends MonitorProvider<MonitorProviderCfg>
049       implements Runnable
050{
051  /** The name to use for the monitor attribute that provides the current request backlog. */
052  public static final String ATTR_CURRENT_BACKLOG = "currentRequestBacklog";
053  /** The name to use for the monitor attribute that provides the average request backlog. */
054  public static final String ATTR_AVERAGE_BACKLOG = "averageRequestBacklog";
055  /**
056   * The name to use for the monitor attribute that provides the maximum
057   * observed request backlog.
058   */
059  public static final String ATTR_MAX_BACKLOG = "maxRequestBacklog";
060  /**
061   * The name to use for the monitor attribute that provides the total number of
062   * operations submitted.
063   */
064  public static final String ATTR_OPS_SUBMITTED = "requestsSubmitted";
065
066
067  /** The maximum backlog observed by polling the queue. */
068  private int maxBacklog;
069
070  /** The total number of times the backlog has been polled. */
071  private long numPolls;
072
073  /** The total backlog observed from periodic polling. */
074  private long totalBacklog;
075
076  /** The parallel work queue instance with which this monitor is associated. */
077  private ParallelWorkQueue workQueue;
078
079  /**
080   * Initializes this monitor provider.  Note that no initialization should be
081   * done here, since it should be performed in the
082   * <CODE>initializeMonitorProvider</CODE> class.
083   *
084   * @param  workQueue  The work queue with which this monitor is associated.
085   */
086  public ParallelWorkQueueMonitor(ParallelWorkQueue workQueue)
087  {
088    this.workQueue = workQueue;
089  }
090
091
092
093  /** {@inheritDoc} */
094  @Override
095  public void initializeMonitorProvider(MonitorProviderCfg configuration)
096         throws ConfigException, InitializationException
097  {
098    maxBacklog   = 0;
099    totalBacklog = 0;
100    numPolls     = 0;
101    scheduleUpdate(this, 0, 10, TimeUnit.SECONDS);
102  }
103
104
105
106  /**
107   * Retrieves the name of this monitor provider.  It should be unique among all
108   * monitor providers, including all instances of the same monitor provider.
109   *
110   * @return  The name of this monitor provider.
111   */
112  @Override
113  public String getMonitorInstanceName()
114  {
115    return "Work Queue";
116  }
117
118
119  /** {@inheritDoc} */
120  @Override
121  public void run()
122  {
123    int backlog = workQueue.size();
124    totalBacklog += backlog;
125    numPolls++;
126
127    if (backlog > maxBacklog)
128    {
129      maxBacklog = backlog;
130    }
131  }
132
133
134
135  /**
136   * Retrieves a set of attributes containing monitor data that should be
137   * returned to the client if the corresponding monitor entry is requested.
138   *
139   * @return  A set of attributes containing monitor data that should be
140   *          returned to the client if the corresponding monitor entry is
141   *          requested.
142   */
143  @Override
144  public ArrayList<Attribute> getMonitorData()
145  {
146    int backlog = workQueue.size();
147    totalBacklog += backlog;
148    numPolls++;
149    if (backlog > maxBacklog)
150    {
151      maxBacklog = backlog;
152    }
153
154    long averageBacklog = (long) (1.0 * totalBacklog / numPolls);
155    long opsSubmitted = workQueue.getOpsSubmitted();
156
157    ArrayList<Attribute> monitorAttrs = new ArrayList<>();
158    putAttribute(monitorAttrs, ATTR_CURRENT_BACKLOG, backlog);
159    putAttribute(monitorAttrs, ATTR_AVERAGE_BACKLOG, averageBacklog);
160    putAttribute(monitorAttrs, ATTR_MAX_BACKLOG, maxBacklog);
161    // The total number of operations submitted.
162    putAttribute(monitorAttrs, ATTR_OPS_SUBMITTED, opsSubmitted);
163
164    return monitorAttrs;
165  }
166
167  private void putAttribute(ArrayList<Attribute> monitorAttrs, String attrName, Object value)
168  {
169    AttributeType attrType = getAttributeTypeOrDefault(attrName, attrName, getDefaultIntegerSyntax());
170    monitorAttrs.add(Attributes.create(attrType, String.valueOf(value)));
171  }
172}