Skip to content

Commit

Permalink
ProfileResult and CollectorResult should print machine readable timin…
Browse files Browse the repository at this point in the history
…g information (#22638)

Currently both ProfileResult and CollectorResult print the timing field in a
human readable string format (e.g. "time": "55.20315000ms"). When trying to
parse this back to a long value, for example to use in the planned high level
java rest client, we can lose precision because of conversion and rounding
issues. This change introduces the additional field `time_in_nanos` that prints
the raw timing value in nanoseconds.
  • Loading branch information
cbuescher authored Jan 16, 2017
1 parent e79b03b commit 056e2f7
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public final class ProfileResult implements Writeable, ToXContent {
private static final ParseField TYPE = new ParseField("type");
private static final ParseField DESCRIPTION = new ParseField("description");
private static final ParseField NODE_TIME = new ParseField("time");
private static final ParseField NODE_TIME_NANOS = new ParseField("time_in_nanos");
private static final ParseField CHILDREN = new ParseField("children");
private static final ParseField BREAKDOWN = new ParseField("breakdown");

Expand Down Expand Up @@ -147,6 +148,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
.field(TYPE.getPreferredName(), type)
.field(DESCRIPTION.getPreferredName(), description)
.field(NODE_TIME.getPreferredName(), String.format(Locale.US, "%.10gms", getTime() / 1000000.0))
.field(NODE_TIME_NANOS.getPreferredName(), getTime())
.field(BREAKDOWN.getPreferredName(), timings);

if (!children.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class CollectorResult implements ToXContent, Writeable {
private static final ParseField NAME = new ParseField("name");
private static final ParseField REASON = new ParseField("reason");
private static final ParseField TIME = new ParseField("time");
private static final ParseField TIME_NANOS = new ParseField("time_in_nanos");
private static final ParseField CHILDREN = new ParseField("children");

/**
Expand Down Expand Up @@ -140,7 +141,8 @@ public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params par
builder = builder.startObject()
.field(NAME.getPreferredName(), getName())
.field(REASON.getPreferredName(), getReason())
.field(TIME.getPreferredName(), String.format(Locale.US, "%.10gms", (double) (getTime() / 1000000.0)));
.field(TIME.getPreferredName(), String.format(Locale.US, "%.10gms", getTime() / 1000000.0))
.field(TIME_NANOS.getPreferredName(), getTime());

if (!children.isEmpty()) {
builder = builder.startArray(CHILDREN.getPreferredName());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.search.profile;

import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.test.ESTestCase;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ProfileResultTests extends ESTestCase {

public void testToXContent() throws IOException {
List<ProfileResult> children = new ArrayList<>();
children.add(new ProfileResult("child1", "desc1", Collections.emptyMap(), Collections.emptyList(), 100L));
children.add(new ProfileResult("child2", "desc2", Collections.emptyMap(), Collections.emptyList(), 123356L));
Map<String, Long> timings = new HashMap<>();
timings.put("key1", 12345L);
timings.put("key2", 6789L);
ProfileResult result = new ProfileResult("someType", "some description", timings, children, 123456L);
XContentBuilder builder = XContentFactory.jsonBuilder().prettyPrint();
result.toXContent(builder, ToXContent.EMPTY_PARAMS);
assertEquals("{\n" +
" \"type\" : \"someType\",\n" +
" \"description\" : \"some description\",\n" +
" \"time\" : \"0.1234560000ms\",\n" +
" \"time_in_nanos\" : 123456,\n" +
" \"breakdown\" : {\n" +
" \"key1\" : 12345,\n" +
" \"key2\" : 6789\n" +
" },\n" +
" \"children\" : [\n" +
" {\n" +
" \"type\" : \"child1\",\n" +
" \"description\" : \"desc1\",\n" +
" \"time\" : \"0.0001000000000ms\",\n" +
" \"time_in_nanos\" : 100,\n" +
" \"breakdown\" : { }\n" +
" },\n" +
" {\n" +
" \"type\" : \"child2\",\n" +
" \"description\" : \"desc2\",\n" +
" \"time\" : \"0.1233560000ms\",\n" +
" \"time_in_nanos\" : 123356,\n" +
" \"breakdown\" : { }\n" +
" }\n" +
" ]\n" +
"}", builder.string());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.elasticsearch.search.profile.query;

import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.test.ESTestCase;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class CollectorResultTests extends ESTestCase {

public void testToXContent() throws IOException {
List<CollectorResult> children = new ArrayList<>();
children.add(new CollectorResult("child1", "reason1", 100L, Collections.emptyList()));
children.add(new CollectorResult("child2", "reason1", 123356L, Collections.emptyList()));
CollectorResult result = new CollectorResult("collectorName", "some reason", 123456L, children);
XContentBuilder builder = XContentFactory.jsonBuilder().prettyPrint();
result.toXContent(builder, ToXContent.EMPTY_PARAMS);
assertEquals("{\n" +
" \"name\" : \"collectorName\",\n" +
" \"reason\" : \"some reason\",\n" +
" \"time\" : \"0.1234560000ms\",\n" +
" \"time_in_nanos\" : 123456,\n" +
" \"children\" : [\n" +
" {\n" +
" \"name\" : \"child1\",\n" +
" \"reason\" : \"reason1\",\n" +
" \"time\" : \"0.0001000000000ms\",\n" +
" \"time_in_nanos\" : 100\n" +
" },\n" +
" {\n" +
" \"name\" : \"child2\",\n" +
" \"reason\" : \"reason1\",\n" +
" \"time\" : \"0.1233560000ms\",\n" +
" \"time_in_nanos\" : 123356\n" +
" }\n" +
" ]\n" +
"}", builder.string());
}
}
Loading

0 comments on commit 056e2f7

Please sign in to comment.