Skip to content

Commit a2fd4c5

Browse files
committed
Merge branch 'master' into refact-base
2 parents d420cd7 + 69e6b46 commit a2fd4c5

File tree

17 files changed

+251
-15
lines changed

17 files changed

+251
-15
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
HEAD_BRANCH_NAME: ${{ github.head_ref }}
2020
BASE_BRANCH_NAME: ${{ github.base_ref }}
2121
TARGET_BRANCH_NAME: ${{ github.base_ref != '' && github.base_ref || github.ref_name }}
22-
RELEASE_BRANCH: ${{ startsWith(github.ref_name, 'release-') || startsWith(github.ref_name, 'test-') || startsWith(github.base_ref, 'release-') }}
22+
RELEASE_BRANCH: ${{ startsWith(github.ref_name, 'release-') || startsWith(github.ref_name, 'test-') }}
2323

2424
strategy:
2525
fail-fast: false
@@ -42,7 +42,7 @@ jobs:
4242
restore-keys: ${{ runner.os }}-m2
4343

4444
- name: Checkout
45-
uses: actions/checkout@v3
45+
uses: actions/checkout@v4
4646
with:
4747
fetch-depth: 2
4848

@@ -88,6 +88,6 @@ jobs:
8888
$TRAVIS_DIR/run-tinkerpop-test.sh $BACKEND tinkerpop
8989
9090
- name: Upload coverage to Codecov
91-
uses: codecov/codecov-action@v3.0.0
91+
uses: codecov/codecov-action@v3
9292
with:
9393
file: ${{ env.REPORT_DIR }}/*.xml

hugegraph-server/hugegraph-api/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
<dependency>
152152
<groupId>io.swagger.core.v3</groupId>
153153
<artifactId>swagger-jaxrs2-jakarta</artifactId>
154-
<version>2.1.9</version>
154+
<version>${swagger.version}</version>
155155
</dependency>
156156

157157
<dependency>

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/arthas/ArthasAPI.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
import com.codahale.metrics.annotation.Timed;
2828
import com.taobao.arthas.agent.attach.ArthasAgent;
2929

30+
import io.swagger.v3.oas.annotations.Operation;
31+
import io.swagger.v3.oas.annotations.tags.Tag;
32+
3033
import jakarta.inject.Singleton;
3134
import jakarta.ws.rs.PUT;
3235
import jakarta.ws.rs.Path;
@@ -35,6 +38,7 @@
3538

3639
@Path("arthas")
3740
@Singleton
41+
@Tag(name = "ArthasAPI")
3842
public class ArthasAPI extends API {
3943

4044
@Context
@@ -43,6 +47,7 @@ public class ArthasAPI extends API {
4347
@PUT
4448
@Timed
4549
@Produces(APPLICATION_JSON_WITH_CHARSET)
50+
@Operation(summary = "start arthas agent")
4651
public Object startArthas() {
4752
HugeConfig config = this.configProvider.get();
4853
HashMap<String, String> configMap = new HashMap<>(4);

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/cypher/CypherAPI.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
import com.codahale.metrics.annotation.Timed;
3535

36+
import io.swagger.v3.oas.annotations.tags.Tag;
37+
3638
import jakarta.inject.Singleton;
3739
import jakarta.ws.rs.Consumes;
3840
import jakarta.ws.rs.GET;
@@ -47,6 +49,7 @@
4749

4850
@Path("graphs/{graph}/cypher")
4951
@Singleton
52+
@Tag(name = "CypherAPI")
5053
public class CypherAPI extends API {
5154

5255
private static final Logger LOG = Log.logger(CypherAPI.class);

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/AccessLogFilter.java

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package org.apache.hugegraph.api.filter;
1919

20+
import static org.apache.hugegraph.api.filter.PathFilter.REQUEST_PARAMS_JSON;
2021
import static org.apache.hugegraph.api.filter.PathFilter.REQUEST_TIME;
2122
import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_FAILED_COUNTER;
2223
import static org.apache.hugegraph.metrics.MetricsUtil.METRICS_PATH_RESPONSE_TIME_HISTOGRAM;
@@ -25,12 +26,20 @@
2526

2627
import java.io.IOException;
2728

29+
import org.apache.hugegraph.config.HugeConfig;
30+
import org.apache.hugegraph.config.ServerOptions;
2831
import org.apache.hugegraph.metrics.MetricsUtil;
32+
import org.apache.hugegraph.metrics.SlowQueryLog;
33+
import org.apache.hugegraph.util.JsonUtil;
34+
import org.apache.hugegraph.util.Log;
35+
import org.slf4j.Logger;
2936

3037
import jakarta.inject.Singleton;
38+
import jakarta.ws.rs.HttpMethod;
3139
import jakarta.ws.rs.container.ContainerRequestContext;
3240
import jakarta.ws.rs.container.ContainerResponseContext;
3341
import jakarta.ws.rs.container.ContainerResponseFilter;
42+
import jakarta.ws.rs.core.Context;
3443
import jakarta.ws.rs.ext.Provider;
3544

3645

@@ -39,6 +48,14 @@
3948
public class AccessLogFilter implements ContainerResponseFilter {
4049

4150
private static final String DELIMETER = "/";
51+
private static final String GRAPHS = "graphs";
52+
private static final String GREMLIN = "gremlin";
53+
private static final String CYPHER = "cypher";
54+
55+
private static final Logger LOG = Log.logger(AccessLogFilter.class);
56+
57+
@Context
58+
private jakarta.inject.Provider<HugeConfig> configProvider;
4259

4360
/**
4461
* Use filter to log request info
@@ -62,13 +79,24 @@ public void filter(ContainerRequestContext requestContext, ContainerResponseCont
6279

6380
// get responseTime
6481
Object requestTime = requestContext.getProperty(REQUEST_TIME);
65-
if(requestTime!=null){
82+
if(requestTime != null){
6683
long now = System.currentTimeMillis();
67-
long responseTime = (now - (long)requestTime);
84+
long start = (Long) requestTime;
85+
long responseTime = now - start;
6886

6987
MetricsUtil.registerHistogram(
7088
join(metricsName, METRICS_PATH_RESPONSE_TIME_HISTOGRAM))
7189
.update(responseTime);
90+
91+
HugeConfig config = configProvider.get();
92+
long timeThreshold = config.get(ServerOptions.SLOW_QUERY_LOG_TIME_THRESHOLD);
93+
94+
// record slow query log
95+
if (timeThreshold > 0 && isSlowQueryLogWhiteAPI(requestContext) && responseTime > timeThreshold) {
96+
SlowQueryLog log = new SlowQueryLog(responseTime, start, (String) requestContext.getProperty(REQUEST_PARAMS_JSON),
97+
method, timeThreshold, path);
98+
LOG.info("Slow query: {}", JsonUtil.toJson(log));
99+
}
72100
}
73101
}
74102

@@ -79,4 +107,18 @@ private String join(String path1, String path2) {
79107
private boolean statusOk(int status){
80108
return status == 200 || status == 201 || status == 202;
81109
}
110+
111+
public static boolean isSlowQueryLogWhiteAPI(ContainerRequestContext context) {
112+
String path = context.getUriInfo().getPath();
113+
String method = context.getRequest().getMethod();
114+
115+
// GraphsAPI/CypherAPI/Job GremlinAPI
116+
if (path.startsWith(GRAPHS)) {
117+
if (method.equals(HttpMethod.GET) || path.endsWith(CYPHER) || path.endsWith(GREMLIN) ){
118+
return true;
119+
}
120+
}
121+
// Raw GremlinAPI
122+
return path.startsWith(GREMLIN);
123+
}
82124
}

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/filter/PathFilter.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@
1717

1818
package org.apache.hugegraph.api.filter;
1919

20+
import static org.apache.hugegraph.api.API.CHARSET;
21+
2022
import java.io.IOException;
23+
import java.io.InputStream;
24+
25+
import org.apache.commons.io.Charsets;
26+
import org.apache.commons.io.IOUtils;
2127

2228
import jakarta.inject.Singleton;
29+
import jakarta.ws.rs.HttpMethod;
2330
import jakarta.ws.rs.container.ContainerRequestContext;
2431
import jakarta.ws.rs.container.ContainerRequestFilter;
2532
import jakarta.ws.rs.container.PreMatching;
33+
import jakarta.ws.rs.core.MultivaluedMap;
2634
import jakarta.ws.rs.ext.Provider;
2735

2836
@Provider
@@ -31,10 +39,26 @@
3139
public class PathFilter implements ContainerRequestFilter {
3240

3341
public static final String REQUEST_TIME = "request_time";
42+
public static final String REQUEST_PARAMS_JSON = "request_params_json";
3443

3544
@Override
3645
public void filter(ContainerRequestContext context)
3746
throws IOException {
3847
context.setProperty(REQUEST_TIME, System.currentTimeMillis());
48+
49+
// record the request json
50+
String method = context.getMethod();
51+
String requestParamsJson = "";
52+
if (method.equals(HttpMethod.POST)) {
53+
requestParamsJson = IOUtils.toString(context.getEntityStream(), Charsets.toCharset(CHARSET));
54+
// replace input stream because we have already read it
55+
InputStream in = IOUtils.toInputStream(requestParamsJson, Charsets.toCharset(CHARSET));
56+
context.setEntityStream(in);
57+
} else if(method.equals(HttpMethod.GET)){
58+
MultivaluedMap<String, String> pathParameters = context.getUriInfo().getPathParameters();
59+
requestParamsJson = pathParameters.toString();
60+
}
61+
62+
context.setProperty(REQUEST_PARAMS_JSON, requestParamsJson);
3963
}
4064
}

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/job/AlgorithmAPI.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import com.codahale.metrics.annotation.Timed;
3737
import com.google.common.collect.ImmutableMap;
3838

39+
import io.swagger.v3.oas.annotations.tags.Tag;
40+
3941
import jakarta.inject.Singleton;
4042
import jakarta.ws.rs.Consumes;
4143
import jakarta.ws.rs.NotFoundException;
@@ -47,6 +49,7 @@
4749

4850
@Path("graphs/{graph}/jobs/algorithm")
4951
@Singleton
52+
@Tag(name = "AlgorithmAPI")
5053
public class AlgorithmAPI extends API {
5154

5255
private static final Logger LOG = Log.logger(RestServer.class);

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/metrics/MetricsAPI.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@
7070
import com.codahale.metrics.Metric;
7171
import com.codahale.metrics.annotation.Timed;
7272

73+
import io.swagger.v3.oas.annotations.Operation;
7374
import io.swagger.v3.oas.annotations.tags.Tag;
75+
7476
import jakarta.annotation.security.RolesAllowed;
7577
import jakarta.inject.Singleton;
7678
import jakarta.ws.rs.GET;
@@ -103,6 +105,7 @@ public MetricsAPI() {
103105
@Path("system")
104106
@Produces(APPLICATION_JSON_WITH_CHARSET)
105107
@RolesAllowed({"admin", "$owner= $action=metrics_read"})
108+
@Operation(summary = "get the system metrics")
106109
public String system() {
107110
return JsonUtil.toJson(this.systemMetrics.metrics());
108111
}
@@ -112,6 +115,7 @@ public String system() {
112115
@Path("backend")
113116
@Produces(APPLICATION_JSON_WITH_CHARSET)
114117
@RolesAllowed({"admin", "$owner= $action=metrics_read"})
118+
@Operation(summary = "get the backend metrics")
115119
public String backend(@Context GraphManager manager) {
116120
Map<String, Map<String, Object>> results = InsertionOrderUtil.newMap();
117121
for (String graph : manager.graphs()) {
@@ -134,6 +138,7 @@ public String backend(@Context GraphManager manager) {
134138
@Path("gauges")
135139
@Produces(APPLICATION_JSON_WITH_CHARSET)
136140
@RolesAllowed({"admin", "$owner= $action=metrics_read"})
141+
@Operation(summary = "get the gauges metrics")
137142
public String gauges() {
138143
ServerReporter reporter = ServerReporter.instance();
139144
return JsonUtil.toJson(reporter.gauges());
@@ -144,6 +149,7 @@ public String gauges() {
144149
@Path("counters")
145150
@Produces(APPLICATION_JSON_WITH_CHARSET)
146151
@RolesAllowed({"admin", "$owner= $action=metrics_read"})
152+
@Operation(summary = "get the counters metrics")
147153
public String counters() {
148154
ServerReporter reporter = ServerReporter.instance();
149155
return JsonUtil.toJson(reporter.counters());
@@ -154,6 +160,7 @@ public String counters() {
154160
@Path("histograms")
155161
@Produces(APPLICATION_JSON_WITH_CHARSET)
156162
@RolesAllowed({"admin", "$owner= $action=metrics_read"})
163+
@Operation(summary = "get the histograms metrics")
157164
public String histograms() {
158165
ServerReporter reporter = ServerReporter.instance();
159166
return JsonUtil.toJson(reporter.histograms());
@@ -164,6 +171,7 @@ public String histograms() {
164171
@Path("meters")
165172
@Produces(APPLICATION_JSON_WITH_CHARSET)
166173
@RolesAllowed({"admin", "$owner= $action=metrics_read"})
174+
@Operation(summary = "get the meters metrics")
167175
public String meters() {
168176
ServerReporter reporter = ServerReporter.instance();
169177
return JsonUtil.toJson(reporter.meters());
@@ -174,6 +182,7 @@ public String meters() {
174182
@Path("timers")
175183
@Produces(APPLICATION_JSON_WITH_CHARSET)
176184
@RolesAllowed({"admin", "$owner= $action=metrics_read"})
185+
@Operation(summary = "get the timers metrics")
177186
public String timers() {
178187
ServerReporter reporter = ServerReporter.instance();
179188
return JsonUtil.toJson(reporter.timers());
@@ -183,6 +192,7 @@ public String timers() {
183192
@Timed
184193
@Produces(APPLICATION_TEXT_WITH_CHARSET)
185194
@RolesAllowed({"admin", "$owner= $action=metrics_read"})
195+
@Operation(summary = "get all base metrics")
186196
public String all(@Context GraphManager manager,
187197
@QueryParam("type") String type) {
188198
if (type != null && type.equals(JSON_STR)) {
@@ -197,6 +207,7 @@ public String all(@Context GraphManager manager,
197207
@Timed
198208
@Produces(APPLICATION_TEXT_WITH_CHARSET)
199209
@RolesAllowed({"admin", "$owner= $action=metrics_read"})
210+
@Operation(summary = "get all statistics metrics")
200211
public String statistics(@QueryParam("type") String type) {
201212
Map<String, Map<String, Object>> metricMap = statistics();
202213

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/api/profile/WhiteIpListAPI.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
import com.codahale.metrics.annotation.Timed;
3838
import com.google.common.collect.ImmutableMap;
3939

40+
import io.swagger.v3.oas.annotations.Operation;
41+
import io.swagger.v3.oas.annotations.tags.Tag;
4042
import jakarta.annotation.security.RolesAllowed;
4143
import jakarta.inject.Singleton;
4244
import jakarta.ws.rs.Consumes;
@@ -50,6 +52,7 @@
5052

5153
@Path("whiteiplist")
5254
@Singleton
55+
@Tag(name = "WhiteIpListAPI")
5356
public class WhiteIpListAPI extends API {
5457

5558
private static final Logger LOG = Log.logger(WhiteIpListAPI.class);
@@ -58,6 +61,7 @@ public class WhiteIpListAPI extends API {
5861
@Timed
5962
@Produces(APPLICATION_JSON_WITH_CHARSET)
6063
@RolesAllowed("admin")
64+
@Operation(summary = "list white ips")
6165
public Map<String, Object> list(@Context GraphManager manager) {
6266
LOG.debug("List white ips");
6367
AuthManager authManager = manager.authManager();
@@ -71,6 +75,7 @@ public Map<String, Object> list(@Context GraphManager manager) {
7175
@Consumes(APPLICATION_JSON)
7276
@Produces(APPLICATION_JSON_WITH_CHARSET)
7377
@RolesAllowed("admin")
78+
@Operation(summary = "update white ip list")
7479
public Map<String, Object> updateWhiteIPs(@Context GraphManager manager, Map<String, Object> actionMap) {
7580
E.checkArgument(actionMap != null,
7681
"Missing argument: actionMap");
@@ -131,6 +136,7 @@ public Map<String, Object> updateWhiteIPs(@Context GraphManager manager, Map<Str
131136
@Timed
132137
@Produces(APPLICATION_JSON_WITH_CHARSET)
133138
@RolesAllowed("admin")
139+
@Operation(summary = "enable/disable the white ip list")
134140
public Map<String, Object> updateStatus(@Context GraphManager manager, @QueryParam("status") String status) {
135141
LOG.debug("Enable or disable white ip list");
136142
E.checkArgument("true".equals(status) ||

hugegraph-server/hugegraph-api/src/main/java/org/apache/hugegraph/config/ServerOptions.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,4 +304,13 @@ public static synchronized ServerOptions instance() {
304304
null,
305305
"jad"
306306
);
307+
308+
public static final ConfigOption<Long> SLOW_QUERY_LOG_TIME_THRESHOLD =
309+
new ConfigOption<>(
310+
"log.slow_query_threshold",
311+
"The threshold time(ms) of logging slow query, " +
312+
"0 means logging slow query is disabled.",
313+
nonNegativeInt(),
314+
1000L
315+
);
307316
}

0 commit comments

Comments
 (0)