Skip to content

Added optional "timestamp" value as part of metric sample#337

Merged
brian-brazil merged 19 commits intoprometheus:masterfrom
felipe-conde-benavides:feature-timestamp
Feb 14, 2018
Merged

Added optional "timestamp" value as part of metric sample#337
brian-brazil merged 19 commits intoprometheus:masterfrom
felipe-conde-benavides:feature-timestamp

Conversation

@felipe-conde-benavides
Copy link
Copy Markdown
Contributor

I'm using an exporter based on this code and it's working fine.

To be honest I'm not using equals() and hashCode() methods, so I haven't test it.

One more thing, about hashCode(): I'm not totally sure if code is totally agree with the current structure, so please check.

@brian-brazil
Copy link
Copy Markdown
Contributor

This is breaking tests, and there should be unittests added for this.

It's be better to take a unboxed value.

return false;
}
Sample other = (Sample) obj;
boolean timestampEquals = true;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the Java 7 java.utils.Objects.equals. This project maintains Java 6 compatibility but it might be tidier to paste in this method and use it compare all the member objects using this method.

static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b)); }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't totally understand what you say:

 boolean timestampEquals = true;
        if ((timestamp != null && other.timestamp == null) || (timestamp == null && other.timestamp != null)) {
        	timestampEquals = false;
        }
        if (timestamp != null && other.timestamp != null) {
        	timestampEquals = other.timestamp.equals(timestamp);
        }

The equals() used here is the same used in other parts of previously existing code, such as:

return other.name.equals(name) && other.labelNames.equals(labelNames)
          && other.labelValues.equals(labelValues) && other.value == value;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion is to based on readability - but it's just a suggestion.

hash = 37 * hash + labelValues.hashCode();
long d = Double.doubleToLongBits(value);
hash = 37 * hash + (int)(d ^ (d >>> 32));
hash = 37 * hash + timestamp.hashCode();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to be wrapped in an if (timestamp != null) check

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, I have changed it, but still not pushed.

writer.write(' ');
writer.write(Collector.doubleToGoString(sample.value));
if (sample.timestamp != null){
writer.write(' ');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you remove the tab and use spaces for indents?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't realize about it, I have changed it, but still not pushed.

long d = Double.doubleToLongBits(value);
hash = 37 * hash + (int)(d ^ (d >>> 32));
if (timestamp != null)
hash = 37 * hash + timestamp.hashCode();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you remove the tab here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, now my Eclipse IDE is configured for use "spaces" (2) instead of "tabs".

return other.name.equals(name) && other.labelNames.equals(labelNames)
&& other.labelValues.equals(labelValues) && other.value == value;
&& other.labelValues.equals(labelValues) && other.value == value
&& timestampEquals;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also appears to be a tab here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, now my Eclipse IDE is configured for use "spaces" (2) instead of "tabs".

@pjfanning
Copy link
Copy Markdown
Contributor

@efelcon would you have time to add the unit tests that Brian asked for?

@felipe-conde-benavides
Copy link
Copy Markdown
Contributor Author

I have the unit tests creation pending, now I have no time to complete it, but I expect to complete before weekend.

@brian-brazil
Copy link
Copy Markdown
Contributor

brian-brazil commented Feb 2, 2018 via email


@Test
public void testCollectWithTimestamp() {
Long now = System.currentTimeMillis();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another tab

public final List<String> labelNames;
public final List<String> labelValues; // Must have same length as labelNames.
public final double value;
public final Long timestamp;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timestampMs would be clearer.

Can you also add a note that this field is subject to change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm agree, this has been changed.

}
Sample other = (Sample) obj;

boolean timestampEquals = true;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit long, I think you can simplify a bit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Now has been reduced to one line.

/**
* Set the optional value for time stamp in epoch format.
*/
public void setTimestamp(Long timestamp) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direct instrumentation has no need for timestamps, these need to be removed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remove this, the Unit Tests for Counter called testCollectWithTimestamp must be removed, because there will be no way for setting the timestamp property (also happen the same for Gauge)). For me there is no problem so, are you agree to remove also the both Unit Tests called testCollectWithTimestamp?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timestamps only work via custom collectors, so tests need to implement one of those.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, now I think I understand what you mean. But I'm afraid I have commited several changes. Tomorrow I will work on this.

writer.write(Collector.doubleToGoString(sample.value));
if (sample.timestamp != null){
writer.write(' ');
writer.write(sample.timestamp.toString());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs unittests

@felipe-conde-benavides
Copy link
Copy Markdown
Contributor Author

felipe-conde-benavides commented Feb 12, 2018

I have added a Unit Test for TextFormat java class (I'm not totally sure if it's all what you want).

Please confirm me if you want me to remove the methods and Unit Tests added in Counter, CounteTest, Gauge and GaugeTest classes ("timestamp" field related).

Copy link
Copy Markdown
Contributor

@brian-brazil brian-brazil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, those should be removed.

}

@Test
public void testMetricOutputWithTimetamp() throws IOException {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stamp

@felipe-conde-benavides
Copy link
Copy Markdown
Contributor Author

felipe-conde-benavides commented Feb 13, 2018

@brian-brazil I have removed all code you request to remove, so I think that all is ready for your check.

TextFormat.write004(writer, registry.metricFamilySamples());
assertEquals("# HELP nolabels help\n"
+ "# TYPE nolabels untyped\n"
+ "nolabels 1.0 "+ now +"\n", writer.toString());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer this was a literal string rather than dynamic, as the output here depends on Java's implicit conversion to string.

@brian-brazil brian-brazil merged commit 5b0a275 into prometheus:master Feb 14, 2018
@brian-brazil
Copy link
Copy Markdown
Contributor

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants