View Javadoc

    1   /**
    2    * Copyright (c) 2002-2011 "Neo Technology,"
    3    * Network Engine for Objects in Lund AB [http://neotechnology.com]
    4    *
    5    * This file is part of Neo4j.
    6    *
    7    * Neo4j is free software: you can redistribute it and/or modify
    8    * it under the terms of the GNU General Public License as published by
    9    * the Free Software Foundation, either version 3 of the License, or
    10   * (at your option) any later version.
    11   *
    12   * This program is distributed in the hope that it will be useful,
    13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15   * GNU General Public License for more details.
    16   *
    17   * You should have received a copy of the GNU General Public License
    18   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    19   */
    20  package org.neo4j.server.webadmin.rest;
    21
    22  import java.util.Date;
    23
    24  import javax.ws.rs.GET;
    25  import javax.ws.rs.Path;
    26  import javax.ws.rs.PathParam;
    27  import javax.ws.rs.core.Context;
    28  import javax.ws.rs.core.Response;
    29
    30  import org.neo4j.server.rest.repr.OutputFormat;
    31  import org.neo4j.server.rrd.RrdFactory;
    32  import org.neo4j.server.webadmin.rest.representations.RrdDataRepresentation;
    33  import org.neo4j.server.webadmin.rest.representations.ServiceDefinitionRepresentation;
    34  import org.rrd4j.ConsolFun;
    35  import org.rrd4j.core.FetchRequest;
    36  import org.rrd4j.core.RrdDb;
    37
    38  /**
    39   * This exposes data from an internal round-robin database that tracks various
    40   * system KPIs over time.
    41   */
    42  @Path( MonitorService.ROOT_PATH )
    43  public class MonitorService implements AdvertisableService
    44  {
    45      private final RrdDb rrdDb;
    46      private final OutputFormat output;
    47
    48      public String getName()
    49      {
    50          return "monitor";
    51      }
    52
    53      public String getServerPath()
    54      {
    55          return ROOT_PATH;
    56      }
    57
    58      public MonitorService( @Context RrdDb rrdDb, @Context OutputFormat output )
    59      {
    60          this.rrdDb = rrdDb;
    61          this.output = output;
    62      }
    63
    64      public static final String ROOT_PATH = "server/monitor";
    65      public static final String DATA_PATH = "/fetch";
    66      public static final String DATA_FROM_PATH = DATA_PATH + "/{start}";
    67      public static final String DATA_SPAN_PATH = DATA_PATH + "/{start}/{stop}";
    68
    69      public static final long MAX_TIMESPAN = 1000l * 60l * 60l * 24l * 365l * 5;
    70      public static final long DEFAULT_TIMESPAN = 1000 * 60 * 60 * 24;
    71
    72
    73      @GET
    74      public Response getServiceDefinition()
    75      {
    76          ServiceDefinitionRepresentation sdr = new ServiceDefinitionRepresentation( ROOT_PATH );
    77          sdr.resourceTemplate( "data_from", MonitorService.DATA_FROM_PATH );
    78          sdr.resourceTemplate( "data_period", MonitorService.DATA_SPAN_PATH );
    79          sdr.resourceUri( "latest_data", MonitorService.DATA_PATH );
    80
    81          return output.ok( sdr );
    82      }
    83
    84      @GET
    85      @Path( DATA_PATH )
    86      public Response getData()
    87      {
    88          long time = new Date().getTime();
    89          return getData( time - DEFAULT_TIMESPAN, time );
    90      }
    91
    92      @GET
    93      @Path( DATA_FROM_PATH )
    94      public Response getData( @PathParam( "start" ) long start )
    95      {
    96          return getData( start, new Date().getTime() );
    97      }
    98
    99      @GET
    100     @Path( DATA_SPAN_PATH )
    101     public Response getData( @PathParam( "start" ) long start,
    102                              @PathParam( "stop" ) long stop )
    103     {
    104         if ( start >= stop || ( stop - start ) > MAX_TIMESPAN )
    105         {
    106             String message = String.format( "Start time must be before stop time, and the total time span can be no bigger than %dms. Time span was %dms.", MAX_TIMESPAN, ( stop - start ) );
    107             return output.badRequest( new IllegalArgumentException( message ) );
    108         }
    109
    110         try
    111         {
    112
    113             FetchRequest request = rrdDb.createFetchRequest(
    114                     ConsolFun.AVERAGE, start, stop,
    115                     getResolutionFor( stop - start ) );
    116
    117             return output.ok( new RrdDataRepresentation( request.fetchData() ) );
    118         } catch ( Exception e )
    119         {
    120             return output.serverError( e );
    121         }
    122     }
    123
    124     private long getResolutionFor( long timespan )
    125     {
    126         long preferred = (long)Math.floor( timespan / ( RrdFactory.STEPS_PER_ARCHIVE * 2 ) );
    127
    128         // Don't allow resolutions smaller than the actual minimum resolution
    129         return preferred > RrdFactory.STEP_SIZE ? preferred : RrdFactory.STEP_SIZE;
    130     }
    131 }