diff --git a/gcloud-java-logging/src/main/java/com/google/cloud/logging/MetricInfo.java b/gcloud-java-logging/src/main/java/com/google/cloud/logging/MetricInfo.java new file mode 100644 index 000000000000..e4f1e97cfded --- /dev/null +++ b/gcloud-java-logging/src/main/java/com/google/cloud/logging/MetricInfo.java @@ -0,0 +1,222 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.google.cloud.logging; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; +import com.google.logging.v2.LogMetric; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Google Cloud Logging metrics describe logs-based metric. The value of the metric is the number of + * log entries that match a logs filter (see {@link #filter()}). + * + * @see Logs-based Metrics + * + */ +public class MetricInfo implements Serializable { + + private static final long serialVersionUID = 666208243838820325L; + + private final String name; + private final String description; + private final String filter; + + /** + * A builder for {@code MetricInfo} objects. + */ + public abstract static class Builder { + + /** + * Sets the name of the metric. Example: {@code severe-errors}. Metric identifiers are + * limited to 1000 characters and can include only the following characters: {@code A-Z}, + * {@code a-z}, {@code 0-9}, and the special characters {@code _-.,+!*',()%/\}. The + * forward-slash character ({@code /}) denotes a hierarchy of name pieces, and it cannot be the + * first character of the name. + */ + public abstract Builder name(String name); + + /** + * Sets an optional description for this metric. Used for documentation purpose. + */ + public abstract Builder description(String description); + + /** + * Sets an advanced logs filter. The value of the metric is the number of log entries that match + * this filter. Example: {@code logName=projects/my-projectid/logs/syslog AND severity>=ERROR}. + * + * @see Advanced Log + * Filters + */ + public abstract Builder filter(String filter); + + /** + * Creates a {@code MetricInfo} object for this builder. + */ + public abstract MetricInfo build(); + } + + static final class BuilderImpl extends Builder { + + private String name; + private String description; + private String filter; + + BuilderImpl(String name, String filter) { + this.name = name; + this.filter = filter; + } + + BuilderImpl(MetricInfo metric) { + this.name = metric.name; + this.description = metric.description; + this.filter = metric.filter; + } + + @Override + public Builder name(String name) { + this.name = name; + return this; + } + + @Override + public Builder description(String description) { + this.description = description; + return this; + } + + @Override + public Builder filter(String filter) { + this.filter = filter; + return this; + } + + @Override + public MetricInfo build() { + return new MetricInfo(this); + } + } + + MetricInfo(BuilderImpl builder) { + this.name = checkNotNull(builder.name); + this.filter = checkNotNull(builder.filter); + this.description = builder.description; + } + + /** + * Returns the name of the metric. Example: {@code severe-errors}. Metric identifiers are + * limited to 1000 characters and can include only the following characters: {@code A-Z}, + * {@code a-z}, {@code 0-9}, and the special characters {@code _-.,+!*',()%/\}. The + * forward-slash character ({@code /}) denotes a hierarchy of name pieces, and it cannot be the + * first character of the name. + */ + public String name() { + return name; + } + + /** + * Returns an optional description for this metric. Used for documentation purpose. + */ + public String description() { + return description; + } + + /** + * Returns an advanced logs filter. The value of the metric is the number of log entries that + * match this filter. Example: + * {@code logName=projects/my-projectid/logs/syslog AND severity>=ERROR}. + * + * @see Advanced Log + * Filters + */ + public String filter() { + return filter; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("name", name) + .add("description", description) + .add("filter", filter) + .toString(); + } + + final boolean baseEquals(MetricInfo metricInfo) { + return Objects.equals(name, metricInfo.name) + && Objects.equals(description, metricInfo.description) + && Objects.equals(filter, metricInfo.filter); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !(obj.getClass().equals(MetricInfo.class))) { + return false; + } + return baseEquals((MetricInfo) obj); + } + + @Override + public int hashCode() { + return Objects.hash(name, description, filter); + } + + /** + * Returns a builder for this {@code MetricInfo} object. + */ + public Builder toBuilder() { + return new BuilderImpl(this); + } + + /** + * Returns a builder for {@code MetricInfo} objects given the name of the metric and its filter. + */ + public static Builder builder(String name, String filter) { + return new BuilderImpl(name, filter); + } + + /** + * Creates a {@code MetricInfo} object given the name of the metric and its filter. + */ + public static MetricInfo of(String name, String filter) { + return new BuilderImpl(name, filter).build(); + } + + LogMetric toPb() { + LogMetric.Builder builder = LogMetric.newBuilder() + .setName(name) + .setFilter(filter); + if (description != null) { + builder.setDescription(description); + } + return builder.build(); + } + + static MetricInfo fromPb(LogMetric metricPb) { + Builder builder = builder(metricPb.getName(), metricPb.getFilter()); + if (!metricPb.getDescription().equals("")) { + builder.description(metricPb.getDescription()); + } + return builder.build(); + } +} diff --git a/gcloud-java-logging/src/test/java/com/google/cloud/logging/MetricInfoTest.java b/gcloud-java-logging/src/test/java/com/google/cloud/logging/MetricInfoTest.java new file mode 100644 index 000000000000..5b4be469cbbb --- /dev/null +++ b/gcloud-java-logging/src/test/java/com/google/cloud/logging/MetricInfoTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.google.cloud.logging; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +public class MetricInfoTest { + + private static final String NAME = "name"; + private static final String FILTER = "logName=projects/my-projectid/logs/syslog"; + private static final String DESCRIPTION = "description"; + private static final String NEW_NAME = "newName"; + private static final String NEW_FILTER = "logName=projects/my-projectid/logs/newSyslog"; + private static final String NEW_DESCRIPTION = "newDescription"; + private static final MetricInfo METRIC_INFO = MetricInfo.builder(NAME, FILTER) + .description(DESCRIPTION) + .build(); + + @Test + public void testOf() { + MetricInfo metricInfo = MetricInfo.of(NAME, FILTER); + assertEquals(NAME, metricInfo.name()); + assertEquals(FILTER, metricInfo.filter()); + assertNull(metricInfo.description()); + } + + @Test + public void testBuilder() { + assertEquals(NAME, METRIC_INFO.name()); + assertEquals(FILTER, METRIC_INFO.filter()); + assertEquals(DESCRIPTION, METRIC_INFO.description()); + } + + @Test + public void testToBuilder() { + compareMetricInfo(METRIC_INFO, METRIC_INFO.toBuilder().build()); + MetricInfo metricInfo = METRIC_INFO.toBuilder() + .name(NEW_NAME) + .description(NEW_DESCRIPTION) + .filter(NEW_FILTER) + .build(); + assertEquals(NEW_NAME, metricInfo.name()); + assertEquals(NEW_FILTER, metricInfo.filter()); + assertEquals(NEW_DESCRIPTION, metricInfo.description()); + metricInfo = metricInfo.toBuilder() + .name(NAME) + .description(DESCRIPTION) + .filter(FILTER) + .build(); + compareMetricInfo(METRIC_INFO, metricInfo); + } + + @Test + public void testToAndFromPb() { + compareMetricInfo(METRIC_INFO, MetricInfo.fromPb(METRIC_INFO.toPb())); + MetricInfo metricInfo = MetricInfo.of(NAME, FILTER); + compareMetricInfo(metricInfo, MetricInfo.fromPb(metricInfo.toPb())); + } + + private void compareMetricInfo(MetricInfo expected, MetricInfo value) { + assertEquals(expected, value); + assertEquals(expected.name(), value.name()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.filter(), value.filter()); + assertEquals(expected.hashCode(), value.hashCode()); + assertEquals(expected.toString(), value.toString()); + } +}