001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 */
018package org.nuxeo.ecm.automation.core.operations.management;
019
020import java.security.Principal;
021import java.util.ArrayList;
022import java.util.Collections;
023import java.util.List;
024
025import net.sf.json.JSONArray;
026import net.sf.json.JSONObject;
027
028import org.nuxeo.ecm.automation.OperationContext;
029import org.nuxeo.ecm.automation.core.Constants;
030import org.nuxeo.ecm.automation.core.annotations.Context;
031import org.nuxeo.ecm.automation.core.annotations.Operation;
032import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
033import org.nuxeo.ecm.automation.core.annotations.Param;
034import org.nuxeo.ecm.automation.core.util.StringList;
035import org.nuxeo.ecm.core.api.Blob;
036import org.nuxeo.ecm.core.api.Blobs;
037import org.nuxeo.ecm.core.api.NuxeoPrincipal;
038import org.nuxeo.runtime.api.Framework;
039import org.nuxeo.runtime.management.counters.CounterHistoryStack;
040import org.nuxeo.runtime.management.counters.CounterManager;
041
042/**
043 * Return the data collected by one or more Counters For each counter 3 series are returned , bare values, delta and
044 * speed
045 *
046 * @author Tiry (tdelprat@nuxeo.com)
047 */
048@Operation(id = GetCounters.ID, category = Constants.CAT_SERVICES, label = "Retrieve counters values", description = "Retrieve data collected by one or more Counters", addToStudio = false)
049public class GetCounters {
050
051    public static final String ID = "Counters.GET";
052
053    @Context
054    protected OperationContext ctx;
055
056    @Param(name = "counterNames", required = true)
057    protected StringList counterNames;
058
059    @OperationMethod
060    public Blob run() {
061
062        CounterManager cm = Framework.getLocalService(CounterManager.class);
063
064        JSONObject collection = new JSONObject();
065
066        Principal principal = ctx.getPrincipal();
067        if (principal instanceof NuxeoPrincipal) {
068            NuxeoPrincipal nuxeoUser = (NuxeoPrincipal) principal;
069            // Only Administrators can access the counters
070            if (nuxeoUser.isAdministrator()) {
071                for (String counterName : counterNames) {
072                    CounterHistoryStack stack = cm.getCounterHistory(counterName);
073
074                    // copy and reverse the list
075                    List<long[]> valueList = new ArrayList<long[]>(stack.getAsList());
076                    Collections.reverse(valueList);
077
078                    JSONObject counter = new JSONObject();
079
080                    // bare values [ [t0,v0], [t1,v1] ...]
081                    JSONArray valueSerie = new JSONArray();
082                    // delta values [ [t1,v1-v0], [t2,v2-v3] ...]
083                    JSONArray deltaSerie = new JSONArray();
084                    // speed values [ [t1,v1-v0/t1-t0], ...]
085                    JSONArray speedSerie = new JSONArray();
086
087                    float lastTS = 0;
088                    float lastValue = 0;
089                    long now = System.currentTimeMillis();
090                    for (long[] values : valueList) {
091
092                        // use seconds
093                        long ts = values[0];
094                        float t = (now - ts) / 1000;
095                        float value = values[1];
096
097                        JSONArray valueArray = new JSONArray();
098                        JSONArray deltaArray = new JSONArray();
099                        JSONArray speedArray = new JSONArray();
100
101                        // bare values
102                        valueArray.add(ts);
103                        valueArray.add(value);
104                        valueSerie.add(valueArray);
105
106                        // delta values
107                        deltaArray.add(ts);
108                        deltaArray.add(value - lastValue);
109                        deltaSerie.add(deltaArray);
110
111                        if (lastTS > 0) {
112                            // speed values
113                            speedArray.add(ts);
114                            float tdelta = lastTS - t;
115                            if (tdelta == 0) {
116                                tdelta = 1;
117                            }
118                            speedArray.add(60 * (value - lastValue) / (tdelta));
119                            speedSerie.add(speedArray);
120                        }
121                        lastTS = t;
122                        lastValue = value;
123                    }
124
125                    counter.put("values", valueSerie);
126                    counter.put("deltas", deltaSerie);
127                    counter.put("speed", speedSerie);
128
129                    collection.put(counterName, counter);
130                }
131            }
132        }
133
134        return Blobs.createBlob(collection.toString(), "application/json");
135    }
136
137}