Skip to content

3.8 GET /_admin/log/entries #383

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a

## [Unreleased]

- added support for getting db log entries via `GET /_admin/log/entries` (ArangoDB v3.8)
- added support for index estimates (ArangoDB v3.8)
- added support for ArangoSearch `AQL`, `Pipeline`, `Stopwords`, `GeoJSON`, `GeoPoint` analyzers
- fixed active failover behavior for the asynchronous driver
Expand Down
22 changes: 19 additions & 3 deletions src/main/java/com/arangodb/ArangoDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.arangodb.entity.ArangoDBVersion;
import com.arangodb.entity.LoadBalancingStrategy;
import com.arangodb.entity.LogEntity;
import com.arangodb.entity.LogEntriesEntity;
import com.arangodb.entity.LogLevelEntity;
import com.arangodb.entity.Permissions;
import com.arangodb.entity.ServerRole;
Expand Down Expand Up @@ -885,15 +886,30 @@ public synchronized ArangoDB build() {
/**
* Returns fatal, error, warning or info log messages from the server's global log.
*
* @param options Additional options, can be null
* @param options
* Additional options, can be null
* @return the log messages
*
* @throws ArangoDBException
* @see <a href=
* "https://www.arangodb.com/docs/stable/http/administration-and-monitoring.html#read-global-logs-from-the-server">API
* @see <a href= "https://www.arangodb.com/docs/stable/http/administration-and-monitoring.html#read-global-logs-from-the-server">API
* Documentation</a>
* @deprecated use {@link #getLogEntries(LogOptions)} instead
*/
LogEntity getLogs(LogOptions options) throws ArangoDBException;

/**
* Returns the server logs
*
* @param options
* Additional options, can be null
* @return the log messages
*
* @see <a href= "https://www.arangodb.com/docs/stable/http/administration-and-monitoring.html#read-global-logs-from-the-server">API
* Documentation</a>
* @since ArangoDB 3.8
*/
LogEntriesEntity getLogEntries(LogOptions options) throws ArangoDBException;

/**
* Returns the server's current loglevel settings.
*
Expand Down
22 changes: 19 additions & 3 deletions src/main/java/com/arangodb/async/ArangoDBAsync.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.arangodb.entity.ArangoDBVersion;
import com.arangodb.entity.LoadBalancingStrategy;
import com.arangodb.entity.LogEntity;
import com.arangodb.entity.LogEntriesEntity;
import com.arangodb.entity.LogLevelEntity;
import com.arangodb.entity.Permissions;
import com.arangodb.entity.ServerRole;
Expand Down Expand Up @@ -280,14 +281,29 @@ public interface ArangoDBAsync extends ArangoSerializationAccessor {
/**
* Returns fatal, error, warning or info log messages from the server's global log.
*
* @param options Additional options, can be null
* @param options
* Additional options, can be null
* @return the log messages
* @see <a href=
* "https://www.arangodb.com/docs/stable/http/administration-and-monitoring.html#read-global-logs-from-the-server">API
*
* @see <a href= "https://www.arangodb.com/docs/stable/http/administration-and-monitoring.html#read-global-logs-from-the-server">API
* Documentation</a>
* @deprecated use {@link #getLogEntries(LogOptions)} instead
*/
CompletableFuture<LogEntity> getLogs(final LogOptions options);

/**
* Returns the server logs
*
* @param options
* Additional options, can be null
* @return the log messages
*
* @see <a href= "https://www.arangodb.com/docs/stable/http/administration-and-monitoring.html#read-global-logs-from-the-server">API
* Documentation</a>
* @since ArangoDB 3.8
*/
CompletableFuture<LogEntriesEntity> getLogEntries(final LogOptions options);

/**
* Returns the server's current loglevel settings.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ public CompletableFuture<LogEntity> getLogs(final LogOptions options) {
return executor.execute(getLogsRequest(options), LogEntity.class);
}

@Override
public CompletableFuture<LogEntriesEntity> getLogEntries(final LogOptions options) {
return executor.execute(getLogEntriesRequest(options), LogEntriesEntity.class);
}

@Override
public CompletableFuture<LogLevelEntity> getLogLevel() {
return executor.execute(getLogLevelRequest(), LogLevelEntity.class);
Expand Down
72 changes: 72 additions & 0 deletions src/main/java/com/arangodb/entity/LogEntriesEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* DISCLAIMER
*
* Copyright 2016 ArangoDB GmbH, Cologne, Germany
*
* Licensed 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.
*
* Copyright holder is ArangoDB GmbH, Cologne, Germany
*/

package com.arangodb.entity;

import java.util.List;

/**
* @author Michele Rastelli
* @see <a href= "https://www.arangodb.com/docs/stable/http/administration-and-monitoring.html#read-global-logs-from-the-server">API
* Documentation</a>
* @since ArangoDB 3.8
*/
public class LogEntriesEntity implements Entity {

private Long total;
private List<Message> messages;

public Long getTotal() {
return total;
}

public List<Message> getMessages() {
return messages;
}

public static class Message {
Long id;
String topic;
String level;
String date;
String message;

public Long getId() {
return id;
}

public String getTopic() {
return topic;
}

public String getLevel() {
return level;
}

public String getDate() {
return date;
}

public String getMessage() {
return message;
}
}

}
5 changes: 5 additions & 0 deletions src/main/java/com/arangodb/internal/ArangoDBImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,11 @@ public LogEntity getLogs(final LogOptions options) throws ArangoDBException {
return executor.execute(getLogsRequest(options), LogEntity.class);
}

@Override
public LogEntriesEntity getLogEntries(final LogOptions options) throws ArangoDBException {
return executor.execute(getLogEntriesRequest(options), LogEntriesEntity.class);
}

@Override
public LogLevelEntity getLogLevel() throws ArangoDBException {
return executor.execute(getLogLevelRequest(), LogLevelEntity.class);
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/arangodb/internal/InternalArangoDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
public abstract class InternalArangoDB<E extends ArangoExecutor> extends ArangoExecuteable<E> {

private static final String PATH_API_ADMIN_LOG = "/_admin/log";
private static final String PATH_API_ADMIN_LOG_ENTRIES = "/_admin/log/entries";
private static final String PATH_API_ADMIN_LOG_LEVEL = "/_admin/log/level";
private static final String PATH_API_ROLE = "/_admin/server/role";
private static final String PATH_ENDPOINTS = "/_api/cluster/endpoints";
Expand Down Expand Up @@ -168,6 +169,18 @@ protected Request getLogsRequest(final LogOptions options) {
.putQueryParam(LogOptions.PROPERTY_SORT, params.getSort());
}

protected Request getLogEntriesRequest(final LogOptions options) {
final LogOptions params = options != null ? options : new LogOptions();
return request(ArangoRequestParam.SYSTEM, RequestType.GET, PATH_API_ADMIN_LOG_ENTRIES)
.putQueryParam(LogOptions.PROPERTY_UPTO, params.getUpto())
.putQueryParam(LogOptions.PROPERTY_LEVEL, params.getLevel())
.putQueryParam(LogOptions.PROPERTY_START, params.getStart())
.putQueryParam(LogOptions.PROPERTY_SIZE, params.getSize())
.putQueryParam(LogOptions.PROPERTY_OFFSET, params.getOffset())
.putQueryParam(LogOptions.PROPERTY_SEARCH, params.getSearch())
.putQueryParam(LogOptions.PROPERTY_SORT, params.getSort());
}

protected Request getLogLevelRequest() {
return request(ArangoRequestParam.SYSTEM, RequestType.GET, PATH_API_ADMIN_LOG_LEVEL);
}
Expand Down
143 changes: 140 additions & 3 deletions src/test/java/com/arangodb/ArangoDBTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,23 @@

package com.arangodb;

import com.arangodb.entity.*;
import com.arangodb.model.*;
import com.arangodb.entity.ArangoDBVersion;
import com.arangodb.entity.DatabaseEntity;
import com.arangodb.entity.License;
import com.arangodb.entity.LogEntity;
import com.arangodb.entity.LogEntriesEntity;
import com.arangodb.entity.LogLevel;
import com.arangodb.entity.LogLevelEntity;
import com.arangodb.entity.Permissions;
import com.arangodb.entity.ServerRole;
import com.arangodb.entity.UserEntity;
import com.arangodb.model.DBCreateOptions;
import com.arangodb.model.DatabaseOptions;
import com.arangodb.model.DatabaseUsersOptions;
import com.arangodb.model.LogOptions;
import com.arangodb.model.LogOptions.SortOrder;
import com.arangodb.model.UserCreateOptions;
import com.arangodb.model.UserUpdateOptions;
import com.arangodb.util.TestUtils;
import com.arangodb.velocypack.exception.VPackException;
import com.arangodb.velocystream.Request;
Expand All @@ -36,7 +50,15 @@
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
Expand Down Expand Up @@ -484,6 +506,121 @@ public void getLogsSortDesc() {
}
}

@Test
public void getLogEntries() {
assumeTrue(isAtLeastVersion(3,8));
final LogEntriesEntity logs = arangoDB.getLogEntries(null);
assertThat(logs, is(notNullValue()));
assertThat(logs.getTotal(), greaterThan(0L));
assertThat((long) logs.getMessages().size(), is(logs.getTotal()));
}

@Test
public void getLogEntriesUpto() {
assumeTrue(isAtLeastVersion(3,8));
final LogEntriesEntity logsUpto = arangoDB.getLogEntries(new LogOptions().upto(LogLevel.WARNING));
assertThat(logsUpto, is(notNullValue()));
assertThat(
logsUpto.getMessages().stream()
.map(LogEntriesEntity.Message::getLevel)
.noneMatch("INFO"::equals),
is(true)
);
}

@Test
public void getLogEntriesLevel() {
assumeTrue(isAtLeastVersion(3,8));
final LogEntriesEntity logsInfo = arangoDB.getLogEntries(new LogOptions().level(LogLevel.INFO));
assertThat(logsInfo, is(notNullValue()));
assertThat(
logsInfo.getMessages().stream()
.map(LogEntriesEntity.Message::getLevel)
.allMatch("INFO"::equals),
is(true)
);
}

@Test
public void getLogEntriesStart() {
assumeTrue(isAtLeastVersion(3,8));
final LogEntriesEntity logs = arangoDB.getLogEntries(null);
final Long firstId = logs.getMessages().get(0).getId();
final LogEntriesEntity logsStart = arangoDB.getLogEntries(new LogOptions().start(firstId + 1));
assertThat(logsStart, is(notNullValue()));
assertThat(
logsStart.getMessages().stream()
.map(LogEntriesEntity.Message::getId)
.filter(firstId::equals)
.count(),
is(0L));
}

@Test
public void getLogEntriesSize() {
assumeTrue(isAtLeastVersion(3,8));
final LogEntriesEntity logs = arangoDB.getLogEntries(null);
int count = logs.getMessages().size();
assertThat(count, greaterThan(0));
final LogEntriesEntity logsSize = arangoDB.getLogEntries(new LogOptions().size(count - 1));
assertThat(logsSize, is(notNullValue()));
assertThat(logsSize.getMessages().size(), is(count - 1));
}

@Test
public void getLogEntriesOffset() {
assumeTrue(isAtLeastVersion(3,8));
final LogEntriesEntity logs = arangoDB.getLogEntries(null);
assertThat(logs.getTotal(), greaterThan(0L));
Long firstId = logs.getMessages().get(0).getId();
final LogEntriesEntity logsOffset = arangoDB.getLogEntries(new LogOptions().offset(1));
assertThat(logsOffset, is(notNullValue()));
assertThat(logsOffset.getMessages().stream()
.map(LogEntriesEntity.Message::getId)
.filter(firstId::equals)
.count()
, is(0L));
}

@Test
public void getLogEntriesSearch() {
assumeTrue(isAtLeastVersion(3,8));
final LogEntriesEntity logs = arangoDB.getLogEntries(null);
final LogEntriesEntity logsSearch = arangoDB.getLogEntries(new LogOptions().search(BaseTest.TEST_DB));
assertThat(logsSearch, is(notNullValue()));
assertThat(logs.getTotal(), greaterThan(logsSearch.getTotal()));
}

@Test
public void getLogEntriesSortAsc() {
assumeTrue(isAtLeastVersion(3,8));
final LogEntriesEntity logs = arangoDB.getLogEntries(new LogOptions().sort(SortOrder.asc));
assertThat(logs, is(notNullValue()));
long lastId = -1;
List<Long> ids = logs.getMessages().stream()
.map(LogEntriesEntity.Message::getId)
.collect(Collectors.toList());
for (final Long id : ids) {
assertThat(id, greaterThan(lastId));
lastId = id;
}
}

@Test
public void getLogEntriesSortDesc() {
assumeTrue(isAtLeastVersion(3,8));
final LogEntriesEntity logs = arangoDB.getLogEntries(new LogOptions().sort(SortOrder.desc));
assertThat(logs, is(notNullValue()));
long lastId = Long.MAX_VALUE;
List<Long> ids = logs.getMessages().stream()
.map(LogEntriesEntity.Message::getId)
.collect(Collectors.toList());
for (final Long id : ids) {
assertThat(lastId, greaterThan(id));
lastId = id;
}
}

@Test
public void getLogLevel() {
assumeTrue(isAtLeastVersion(3, 7)); // it fails in 3.6 active-failover (BTS-362)
Expand Down
Loading