blob: 34eaba269de6742aa38b04f073150fd4c999e907 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.fuseki.ctl;
import static java.lang.String.format;
import static org.apache.jena.riot.WebContent.charsetUTF8;
import static org.apache.jena.riot.WebContent.contentTypeTextPlain;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.jena.atlas.json.JsonBuilder;
import org.apache.jena.atlas.json.JsonObject;
import org.apache.jena.atlas.json.JsonValue;
import org.apache.jena.fuseki.server.*;
import org.apache.jena.fuseki.servlets.HttpAction;
import org.apache.jena.fuseki.servlets.ServletOps;
public class ActionStats extends ActionContainerItem
{
// For endpoint with "" as name.
private static String emptyNameKeyPrefix = "_";
public ActionStats() { super(); }
@Override
public void validate(HttpAction action) {}
// This does not consult the system database for dormant etc.
protected JsonValue execCommonContainer(HttpAction action) {
if ( action.verbose )
action.log.info(format("[%d] GET stats all", action.id));
return generateStats(action.getDataAccessPointRegistry());
}
public static JsonObject generateStats(DataAccessPointRegistry registry) {
JsonBuilder builder = new JsonBuilder();
builder.startObject("top");
builder.key(ServerConst.datasets);
builder.startObject("datasets");
registry.forEach((name, access)->statsDataset(builder, access));
builder.finishObject("datasets");
builder.finishObject("top");
return builder.build().getAsObject();
}
protected JsonValue execCommonItem(HttpAction action) {
String datasetPath = getItemDatasetName(action);
if ( action.verbose )
action.log.info(format("[%d] GET stats dataset %s", action.id, datasetPath));
JsonBuilder builder = new JsonBuilder();
DataAccessPoint dap = getItemDataAccessPoint(action, datasetPath);
if ( dap == null )
ServletOps.errorNotFound(datasetPath);
builder.startObject("TOP");
builder.key(ServerConst.datasets);
builder.startObject("datasets");
statsDataset(builder, datasetPath, action.getDataAccessPointRegistry());
builder.finishObject("datasets");
builder.finishObject("TOP");
return builder.build();
}
public static JsonObject generateStats(DataAccessPoint access) {
JsonBuilder builder = new JsonBuilder();
statsDataset(builder, access);
return builder.build().getAsObject();
}
private void statsDataset(JsonBuilder builder, String name, DataAccessPointRegistry registry) {
DataAccessPoint access = registry.get(name);
statsDataset(builder, access);
}
private static void statsDataset(JsonBuilder builder, DataAccessPoint access) {
// Object started
builder.key(access.getName());
DataService dSrv = access.getDataService();
builder.startObject("counters");
builder.key(CounterName.Requests.getName()).value(dSrv.getCounters().value(CounterName.Requests));
builder.key(CounterName.RequestsGood.getName()).value(dSrv.getCounters().value(CounterName.RequestsGood));
builder.key(CounterName.RequestsBad.getName()).value(dSrv.getCounters().value(CounterName.RequestsBad));
builder.key(ServerConst.endpoints).startObject("endpoints");
int unique = 0;
for ( Operation operName : dSrv.getOperations() ) {
List<Endpoint> endpoints = access.getDataService().getEndpoints(operName);
for ( Endpoint endpoint : endpoints ) {
String k = endpoint.getName();
if ( StringUtils.isEmpty(k) )
k = emptyNameKeyPrefix+(++unique);
// Endpoint names are unique for a given service.
builder.key(k);
builder.startObject();
operationCounters(builder, endpoint);
builder.key(ServerConst.operation).value(operName.getJsonName());
builder.key(ServerConst.description).value(operName.getDescription());
builder.finishObject();
}
}
builder.finishObject("endpoints");
builder.finishObject("counters");
}
private static void operationCounters(JsonBuilder builder, Endpoint operation) {
for (CounterName cn : operation.getCounters().counters()) {
Counter c = operation.getCounters().get(cn);
builder.key(cn.getName()).value(c.value());
}
}
private void statsTxt(HttpServletResponse resp, DataAccessPointRegistry registry) throws IOException {
ServletOutputStream out = resp.getOutputStream();
resp.setContentType(contentTypeTextPlain);
resp.setCharacterEncoding(charsetUTF8);
Iterator<String> iter = registry.keys().iterator();
while (iter.hasNext()) {
String ds = iter.next();
DataAccessPoint desc = registry.get(ds);
statsTxt(out, desc);
if ( iter.hasNext() )
out.println();
}
out.flush();
}
private void statsTxt(ServletOutputStream out, DataAccessPoint desc) throws IOException {
DataService dSrv = desc.getDataService();
out.println("Dataset: " + desc.getName());
out.println(" Requests = " + dSrv.getCounters().value(CounterName.Requests));
out.println(" Good = " + dSrv.getCounters().value(CounterName.RequestsGood));
out.println(" Bad = " + dSrv.getCounters().value(CounterName.RequestsBad));
out.println(" SPARQL Query:");
out.println(" Request = " + counter(dSrv, Operation.Query, CounterName.Requests));
out.println(" Good = " + counter(dSrv, Operation.Query, CounterName.RequestsGood));
out.println(" Bad requests = " + counter(dSrv, Operation.Query, CounterName.RequestsBad));
out.println(" Timeouts = " + counter(dSrv, Operation.Query, CounterName.QueryTimeouts));
out.println(" Bad exec = " + counter(dSrv, Operation.Query, CounterName.QueryExecErrors));
out.println(" IO Errors = " + counter(dSrv, Operation.Query, CounterName.QueryIOErrors));
out.println(" SPARQL Update:");
out.println(" Request = " + counter(dSrv, Operation.Update, CounterName.Requests));
out.println(" Good = " + counter(dSrv, Operation.Update, CounterName.RequestsGood));
out.println(" Bad requests = " + counter(dSrv, Operation.Update, CounterName.RequestsBad));
out.println(" Bad exec = " + counter(dSrv, Operation.Update, CounterName.UpdateExecErrors));
out.println(" Upload:");
out.println(" Requests = " + counter(dSrv, Operation.Upload, CounterName.Requests));
out.println(" Good = " + counter(dSrv, Operation.Upload, CounterName.RequestsGood));
out.println(" Bad = " + counter(dSrv, Operation.Upload, CounterName.RequestsBad));
out.println(" SPARQL Graph Store Protocol:");
out.println(" GETs = " + gspValue(dSrv, CounterName.HTTPget) + " (good=" + gspValue(dSrv, CounterName.HTTPgetGood)
+ "/bad=" + gspValue(dSrv, CounterName.HTTPgetBad) + ")");
out.println(" PUTs = " + gspValue(dSrv, CounterName.HTTPput) + " (good=" + gspValue(dSrv, CounterName.HTTPputGood)
+ "/bad=" + gspValue(dSrv, CounterName.HTTPputBad) + ")");
out.println(" POSTs = " + gspValue(dSrv, CounterName.HTTPpost) + " (good=" + gspValue(dSrv, CounterName.HTTPpostGood)
+ "/bad=" + gspValue(dSrv, CounterName.HTTPpostBad) + ")");
out.println(" PATCHs = " + gspValue(dSrv, CounterName.HTTPpatch) + " (good=" + gspValue(dSrv, CounterName.HTTPpatchGood)
+ "/bad=" + gspValue(dSrv, CounterName.HTTPpatchBad) + ")");
out.println(" DELETEs = " + gspValue(dSrv, CounterName.HTTPdelete) + " (good=" + gspValue(dSrv, CounterName.HTTPdeleteGood)
+ "/bad=" + gspValue(dSrv, CounterName.HTTPdeleteBad) + ")");
out.println(" HEADs = " + gspValue(dSrv, CounterName.HTTPhead) + " (good=" + gspValue(dSrv, CounterName.HTTPheadGood)
+ "/bad=" + gspValue(dSrv, CounterName.HTTPheadBad) + ")");
}
private long counter(DataService dSrv, Operation operation, CounterName cName) {
return 0;
}
private long gspValue(DataService dSrv, CounterName cn) {
return counter(dSrv, Operation.GSP_RW, cn) +
counter(dSrv, Operation.GSP_R, cn);
}
@Override
protected JsonValue execPostContainer(HttpAction action) {
return execCommonContainer(action);
}
@Override
protected JsonValue execPostItem(HttpAction action) {
return execCommonItem(action);
}
@Override
protected JsonValue execGetContainer(HttpAction action) {
return execCommonContainer(action);
}
@Override
protected JsonValue execGetItem(HttpAction action) {
return execCommonItem(action);
}
}