From 99640d1af40cc4e77edbf4c6cdc18c62cdf71b9d Mon Sep 17 00:00:00 2001 From: Bhinav Sura Date: Fri, 16 Sep 2016 16:13:06 -0700 Subject: [PATCH] Manual merge of 2.0 into develop --- .../salesforce/dva/argus/client/Alerter.java | 2 +- .../service/alert/notifier/GOCNotifier.java | 20 +- .../service/alert/notifier/GusNotifier.java | 564 +++++++++--------- .../metric/transform/GroupByTransform.java | 82 +++ .../metric/transform/TransformFactory.java | 2 +- .../schema/AsyncHbaseSchemaService.java | 126 ++-- ArgusCore/src/main/javacc/MetricReader.jj | 5 +- .../transform/GroupByTransformTest.java | 330 ++++++++++ ...rTest.testFunctionsWithConstant.properties | 287 ++++----- ArgusWeb/app/js/controllers/alertsDetail.js | 2 +- .../ws/resources/DiscoveryResources.java | 25 +- 11 files changed, 933 insertions(+), 512 deletions(-) create mode 100644 ArgusCore/src/main/java/com/salesforce/dva/argus/service/metric/transform/GroupByTransform.java create mode 100644 ArgusCore/src/test/java/com/salesforce/dva/argus/service/metric/transform/GroupByTransformTest.java diff --git a/ArgusClient/src/main/java/com/salesforce/dva/argus/client/Alerter.java b/ArgusClient/src/main/java/com/salesforce/dva/argus/client/Alerter.java index 07fa5c206..940e239e6 100644 --- a/ArgusClient/src/main/java/com/salesforce/dva/argus/client/Alerter.java +++ b/ArgusClient/src/main/java/com/salesforce/dva/argus/client/Alerter.java @@ -77,7 +77,7 @@ public void run() { while (!Thread.currentThread().isInterrupted()) { try { jobCounter.addAndGet(service.executeScheduledAlerts(10, timeout).size()); - LOGGER.info("alerts evaluated so far: ", jobCounter.get()); + LOGGER.info("alerts evaluated so far: {}", jobCounter.get()); Thread.sleep(POLL_INTERVAL_MS); } catch (InterruptedException ex) { LOGGER.info("Execution was interrupted."); diff --git a/ArgusCore/src/main/java/com/salesforce/dva/argus/service/alert/notifier/GOCNotifier.java b/ArgusCore/src/main/java/com/salesforce/dva/argus/service/alert/notifier/GOCNotifier.java index 12e751e22..c4ab83aba 100644 --- a/ArgusCore/src/main/java/com/salesforce/dva/argus/service/alert/notifier/GOCNotifier.java +++ b/ArgusCore/src/main/java/com/salesforce/dva/argus/service/alert/notifier/GOCNotifier.java @@ -45,6 +45,7 @@ import com.salesforce.dva.argus.system.SystemConfiguration; import com.salesforce.dva.argus.system.SystemException; +import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.sql.Date; import java.text.MessageFormat; @@ -95,13 +96,13 @@ public GOCNotifier(MetricService metricService, AnnotationService annotationServ //~ Methods ************************************************************************************************************************************** - private PostMethod getRequestMethod(boolean refresh, String id) { + private PostMethod getRequestMethod(boolean refresh, String id) throws UnsupportedEncodingException { GOCTransport gocTransport = new GOCTransport(); EndpointInfo endpointInfo = gocTransport.getEndpointInfo(_config, _logger, refresh); // Create upsert URI with PATCH method PostMethod post = new PostMethod(String.format("%s/services/data/v25.0/sobjects/SM_Alert__c/%s/%s", endpointInfo.getEndPoint(), - GOCData.SM_ALERT_ID__C_FIELD, id)) { + urlEncode(GOCData.SM_ALERT_ID__C_FIELD), urlEncode(id))) { @Override public String getName() { @@ -144,9 +145,10 @@ public void sendMessage(Severity severity, String className, String elementName, for (int i = 0; i < 2; i++) { - PostMethod post = getRequestMethod(refresh, gocData.getsm_Alert_Id__c()); + PostMethod post = null; try { + post=getRequestMethod(refresh, gocData.getsm_Alert_Id__c()); post.setRequestEntity(new StringRequestEntity(gocData.toJSON(), "application/json", null)); int respCode = httpclient.executeMethod(post); @@ -166,7 +168,9 @@ public void sendMessage(Severity severity, String className, String elementName, _logger.error("Failure - send GOC++ having element '{}' event '{}' severity {}. Exception '{}'", elementName, eventName, severity.name(), e); } finally { - post.releaseConnection(); + if(post != null){ + post.releaseConnection(); + } } } } catch (RuntimeException ex) { @@ -268,6 +272,10 @@ public Properties getNotifierProperties() { return notifierProps; } + private String urlEncode(String s) throws UnsupportedEncodingException{ + return URLEncoder.encode(s,org.apache.commons.lang3.CharEncoding.UTF_8).replace("+", "%20"); + } + //~ Enums **************************************************************************************************************************************** /** @@ -296,9 +304,9 @@ public enum Property { /** The GOC password with which to authenticate. */ GOC_PWD("notifier.property.goc.password", "test_password"), /** The GOC proxy host. */ - GOC_PROXY_HOST("notifier.property.goc.proxy.host", ""), + GOC_PROXY_HOST("notifier.property.proxy.host", ""), /** The GOC port. */ - GOC_PROXY_PORT("notifier.property.goc.proxy.port", ""), + GOC_PROXY_PORT("notifier.property.proxy.port", ""), /** The GOC client ID. */ GOC_CLIENT_ID("notifier.property.goc.client.id", "default_client_id"), /** The GOC client secret. */ diff --git a/ArgusCore/src/main/java/com/salesforce/dva/argus/service/alert/notifier/GusNotifier.java b/ArgusCore/src/main/java/com/salesforce/dva/argus/service/alert/notifier/GusNotifier.java index b659391fd..d6c8a490d 100644 --- a/ArgusCore/src/main/java/com/salesforce/dva/argus/service/alert/notifier/GusNotifier.java +++ b/ArgusCore/src/main/java/com/salesforce/dva/argus/service/alert/notifier/GusNotifier.java @@ -28,10 +28,33 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ - + package com.salesforce.dva.argus.service.alert.notifier; +import static com.salesforce.dva.argus.system.SystemAssert.requireArgument; + +import java.io.IOException; +import java.net.URLEncoder; +import java.sql.Date; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import javax.persistence.EntityManager; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.commons.httpclient.params.HttpConnectionManagerParams; +import org.apache.http.message.BasicNameValuePair; +import org.slf4j.Logger; + import com.google.gson.Gson; +import com.google.gson.JsonObject; import com.google.inject.Inject; import com.google.inject.Provider; import com.salesforce.dva.argus.entity.Notification; @@ -43,299 +66,268 @@ import com.salesforce.dva.argus.service.MetricService; import com.salesforce.dva.argus.service.alert.DefaultAlertService.NotificationContext; import com.salesforce.dva.argus.system.SystemConfiguration; -import joptsimple.internal.Strings; -import org.apache.http.HttpResponse; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.params.CookiePolicy; -import org.apache.http.client.params.HttpClientParams; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; -import org.apache.http.protocol.HTTP; -import org.apache.http.util.EntityUtils; -import org.slf4j.Logger; -import java.io.IOException; -import java.net.URLEncoder; -import java.sql.Date; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import javax.persistence.EntityManager; -import static com.salesforce.dva.argus.system.SystemAssert.requireArgument; +import joptsimple.internal.Strings; /** * Chatter Notifier: api user can only post alert to PUBLIC group * * @author Ruofan Zhang (rzhang@salesforce.com) */ -@SuppressWarnings("deprecation") public class GusNotifier extends AuditNotifier { - //~ Static fields/initializers ******************************************************************************************************************* - - /** - * CredentialPair stores name/value pair in the request. - * - * @author Tom Valine (tvaline@salesforce.com) - */ - //~ Instance fields ****************************************************************************************************************************** - - @SLF4JTypeListener.InjectLogger - private Logger _logger; - - //~ Constructors ********************************************************************************************************************************* - - /** - * Creates a new GusNotifier object. - * - * @param metricService The metric service to use. Cannot be null. - * @param annotationService The annotation service to use. Cannot be null. - * @param auditService The audit service to use. Cannot be null. - * @param mailService The mail service to use. Cannot be null. - * @param config The system configuration. Cannot be null. - * @param emf The entity manager factory to use. Cannot be null. - */ - @Inject - public GusNotifier(MetricService metricService, AnnotationService annotationService, AuditService auditService, MailService mailService, - SystemConfiguration config, Provider emf) { - super(metricService, annotationService, auditService, config, emf); - requireArgument(mailService != null, "Mail service cannot be null."); - requireArgument(config != null, "The configuration cannot be null."); - } - - //~ Methods ************************************************************************************************************************************** - - @Override - public String getName() { - return GusNotifier.class.getName(); - } - - @Override - protected void sendAdditionalNotification(NotificationContext context) { - requireArgument(context != null, "Notification context cannot be null."); - super.sendAdditionalNotification(context); - - Notification notification = null; - Trigger trigger = null; - - for (Notification tempNotification : context.getAlert().getNotifications()) { - if (tempNotification.getName().equalsIgnoreCase(context.getNotification().getName())) { - notification = tempNotification; - break; - } - } - requireArgument(notification != null, "Notification in notification context cannot be null."); - for (Trigger tempTrigger : context.getAlert().getTriggers()) { - if (tempTrigger.getName().equalsIgnoreCase(context.getTrigger().getName())) { - trigger = tempTrigger; - break; - } - } - requireArgument(trigger != null, "Trigger in notification context cannot be null."); - - Set to = new HashSet<>(notification.getSubscriptions()); - String feed = generateGusFeed(notification, trigger, context); - - postToGus(to, feed); - } - - private String generateGusFeed(Notification notification, Trigger trigger, NotificationContext context) { - StringBuilder sb = new StringBuilder(); - String notificationName = context.getNotification().getName(); - String alertName = context.getAlert().getName(); - String triggerFiredTime = DATE_FORMATTER.get().format(new Date(context.getTriggerFiredTime())); - String triggerName = trigger.getName(); - String notificationCooldownExpiraton = DATE_FORMATTER.get().format(new Date(context.getCoolDownExpiration())); - String metricExpression = context.getAlert().getExpression(); - String triggerDetails = getTriggerDetails(trigger); - String triggerEventValue = context.getTriggerEventValue(); - Object[] arguments = new Object[] { - notificationName, alertName, triggerFiredTime, triggerName, notificationCooldownExpiraton, metricExpression, triggerDetails, - triggerEventValue - }; - - /** gus feed template for notification information. */ - String gusFeedNotificationTemplate = "Alert Notification {0} is triggered, more info as following:\n" + "Alert {1} was triggered at {2}\n" + - "Notification: {0}\n" + - "Triggered by: {3}\n" + "Notification is on cooldown until: {4}\n" + - "Evaluated metric expression: {5}\n" + "Trigger details: {6}\n" + - "Triggering event value: {7}\n\n"; - - sb.append(MessageFormat.format(gusFeedNotificationTemplate, arguments)); - - /** gus feed template for links. */ - String gusFeedLinkTemplate = "Click here to view {0}\n{1}\n"; - - for (String metricToAnnotate : notification.getMetricsToAnnotate()) { - sb.append(MessageFormat.format(gusFeedLinkTemplate, "the annotated series for", - super.getMetricUrl(metricToAnnotate, context.getTriggerFiredTime()))); - } - sb.append(MessageFormat.format(gusFeedLinkTemplate, "alert definition.", super.getAlertUrl(notification.getAlert().getId()))); - return sb.toString(); - } - - private void postToGus(Set to, String feed) { - // So far works for only one group, will accept a set of string in future. - String groupId = to.toArray(new String[to.size()])[0]; - HttpPost chatterIt = new HttpPost(); - - try { - String gusPost = MessageFormat.format("{0}&subjectId={1}&text={2}", - _config.getValue(Property.POST_ENDPOINT.getName(), Property.POST_ENDPOINT.getDefaultValue()), groupId, - URLEncoder.encode(feed.toString(), "UTF-8")); - - chatterIt = new HttpPost(gusPost); - chatterIt.setHeader("Authorization", "Bearer " + generateAccessToken()); - - @SuppressWarnings("resource") - DefaultHttpClient httpclient = new DefaultHttpClient(); - - httpclient.execute(chatterIt); - } catch (Exception e) { - _logger.error("Throws Exception when posting to gus group {} with subject {}.", groupId, feed); - } finally { - chatterIt.releaseConnection(); - } - } - - private String generateAccessToken() { - // Set up an HTTP client that makes a connection to REST API. - @SuppressWarnings("resource") - DefaultHttpClient client = new DefaultHttpClient(); - HttpParams params = client.getParams(); - - HttpClientParams.setCookiePolicy(params, CookiePolicy.RFC_2109); - params.setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 30000); - - HttpPost oauthPost = new HttpPost(); - - try { - // Send a post request to the OAuth URL. - oauthPost = new HttpPost(_config.getValue(Property.GUS_ENDPOINT.getName(), Property.GUS_ENDPOINT.getDefaultValue())); - - // generate the request body - List paraList = Arrays.asList("grant_type", "username", "password", "client_id", "client_secret"); - - oauthPost.setEntity(new UrlEncodedFormEntity(generateParameterBody(paraList), HTTP.UTF_8)); - - // Execute the request. - HttpResponse response = client.execute(oauthPost); - - // Get access token - @SuppressWarnings("unchecked") - Map oauthLoginResponse = new Gson().fromJson(EntityUtils.toString(response.getEntity()), Map.class); - String accessToken = oauthLoginResponse.get("access_token"); - - return accessToken; - } catch (RuntimeException | IOException e) { - _logger.error("Encoding Exception when generating access token {}", Property.ARGUS_GUS_USER.getDefaultValue()); - } finally { - oauthPost.releaseConnection(); - } - return Strings.EMPTY; - } - - /** - * Enumerates the name value pairs to insert into the notification body. - * - * @param paraList The parameter list. Cannot be null, but may be empty. - * - * @return The list of corresponding name value pairs. Will never return null, but may be empty. - */ - public List generateParameterBody(List paraList) { - List parametersBody = new ArrayList<>(); - - for (String str : paraList) { - parametersBody.add(generateNameValuePair(str)); - } - return parametersBody; - } - - /** - * Generates a basic name value pair based on the given parameter name. - * - * @param paraName The parameter name. Cannot be null or empty. - * - * @return The corresponding name value pair. - * - * @throws UnsupportedOperationException If the specified parameter doesn't have a corresponding GUS property. - */ - public BasicNameValuePair generateNameValuePair(String paraName) { - switch (paraName) { - case "grant_type": - return new BasicNameValuePair(paraName, _config.getValue(Property.GRANT_TYPE_PWD.getName(), Property.GRANT_TYPE_PWD.getDefaultValue())); - case "username": - return new BasicNameValuePair(paraName, _config.getValue(Property.ARGUS_GUS_USER.getName(), Property.ARGUS_GUS_USER.getDefaultValue())); - case "password": - return new BasicNameValuePair(paraName, _config.getValue(Property.ARGUS_GUS_PWD.getName(), Property.ARGUS_GUS_PWD.getDefaultValue())); - case "client_id": - return new BasicNameValuePair(paraName, _config.getValue(Property.GUS_CLIENT_ID.getName(), Property.GUS_CLIENT_ID.getDefaultValue())); - case "client_secret": - return new BasicNameValuePair(paraName, _config.getValue(Property.GUS_CLIENT_SECRET.getName(), Property.GUS_CLIENT_SECRET.getDefaultValue())); - default: - throw new UnsupportedOperationException(paraName); - } - } - - @Override - public Properties getNotifierProperties() { - Properties result = super.getNotifierProperties(); - - for( Property property : Property.values()) { - result.put(property.getName(), property.getDefaultValue()); - } - return result; - } - - public enum Property { - /** The GUS grant type password. */ - GRANT_TYPE_PWD("notifier.property.alert.grant_type_pwd", "password"), - /** The GUS user name. */ - ARGUS_GUS_USER("notifier.property.alert.gus_user", "test@test.com"), - /** The GUS password. */ - ARGUS_GUS_PWD("notifier.property.alert.gus_pwd", "password"), - /** The GUS endpoint. */ - GUS_ENDPOINT("notifier.property.alert.gus_endpoint", "https://gus.test.com"), - /** The GUS client ID. */ - GUS_CLIENT_ID("notifier.property.alert.gus_client_id", "test123"), - /** The GUS client secret. */ - GUS_CLIENT_SECRET("notifier.property.alert.gus_client_secret", "password"), - /** The GUS post endpoint. */ - POST_ENDPOINT("notifier.property.alert.gus_post_endpoint", "https://gus.test.com"); - - private final String _name; - private final String _defaultValue; - - private Property(String name, String defaultValue) { - _name = name; - _defaultValue = defaultValue; - } - - /** - * Returns the property name. - * - * @return The property name. - */ - public String getName() { - return _name; - } - - /** - * Returns the default value. - * - * @return The default value. - */ - public String getDefaultValue() { - return _defaultValue; - } - } + //~ Static fields/initializers ******************************************************************************************************************* + private static final int CONNECTION_TIMEOUT_MILLIS = 10000; + private static final int READ_TIMEOUT_MILLIS = 10000; + private static final String UTF_8 = "UTF-8"; + + //~ Instance fields ****************************************************************************************************************************** + @SLF4JTypeListener.InjectLogger + private Logger _logger; + private final MultiThreadedHttpConnectionManager theConnectionManager; + { + theConnectionManager = new MultiThreadedHttpConnectionManager(); + + HttpConnectionManagerParams params = theConnectionManager.getParams(); + + params.setConnectionTimeout(CONNECTION_TIMEOUT_MILLIS); + params.setSoTimeout(READ_TIMEOUT_MILLIS); + } + + //~ Constructors ********************************************************************************************************************************* + + /** + * Creates a new GusNotifier object. + * + * @param metricService The metric service to use. Cannot be null. + * @param annotationService The annotation service to use. Cannot be null. + * @param auditService The audit service to use. Cannot be null. + * @param mailService The mail service to use. Cannot be null. + * @param config The system configuration. Cannot be null. + * @param emf The entity manager factory to use. Cannot be null. + */ + @Inject + public GusNotifier(MetricService metricService, AnnotationService annotationService, AuditService auditService, MailService mailService, + SystemConfiguration config, Provider emf) { + super(metricService, annotationService, auditService, config, emf); + requireArgument(mailService != null, "Mail service cannot be null."); + requireArgument(config != null, "The configuration cannot be null."); + } + + //~ Methods ************************************************************************************************************************************** + + @Override + public String getName() { + return GusNotifier.class.getName(); + } + + @Override + protected void sendAdditionalNotification(NotificationContext context) { + requireArgument(context != null, "Notification context cannot be null."); + super.sendAdditionalNotification(context); + + Notification notification = null; + Trigger trigger = null; + + for (Notification tempNotification : context.getAlert().getNotifications()) { + if (tempNotification.getName().equalsIgnoreCase(context.getNotification().getName())) { + notification = tempNotification; + break; + } + } + requireArgument(notification != null, "Notification in notification context cannot be null."); + for (Trigger tempTrigger : context.getAlert().getTriggers()) { + if (tempTrigger.getName().equalsIgnoreCase(context.getTrigger().getName())) { + trigger = tempTrigger; + break; + } + } + requireArgument(trigger != null, "Trigger in notification context cannot be null."); + + Set to = new HashSet<>(notification.getSubscriptions()); + String feed = generateGusFeed(notification, trigger, context); + + postToGus(to, feed); + } + + private String generateGusFeed(Notification notification, Trigger trigger, NotificationContext context) { + StringBuilder sb = new StringBuilder(); + String notificationName = context.getNotification().getName(); + String alertName = context.getAlert().getName(); + String triggerFiredTime = DATE_FORMATTER.get().format(new Date(context.getTriggerFiredTime())); + String triggerName = trigger.getName(); + String notificationCooldownExpiraton = DATE_FORMATTER.get().format(new Date(context.getCoolDownExpiration())); + String metricExpression = context.getAlert().getExpression(); + String triggerDetails = getTriggerDetails(trigger); + String triggerEventValue = context.getTriggerEventValue(); + Object[] arguments = new Object[] { + notificationName, alertName, triggerFiredTime, triggerName, notificationCooldownExpiraton, metricExpression, triggerDetails, + triggerEventValue + }; + + /** gus feed template for notification information. */ + String gusFeedNotificationTemplate = "Alert Notification {0} is triggered, more info as following:\n" + "Alert {1} was triggered at {2}\n" + + "Notification: {0}\n" + + "Triggered by: {3}\n" + "Notification is on cooldown until: {4}\n" + + "Evaluated metric expression: {5}\n" + "Trigger details: {6}\n" + + "Triggering event value: {7}\n\n"; + + sb.append(MessageFormat.format(gusFeedNotificationTemplate, arguments)); + + /** gus feed template for links. */ + String gusFeedLinkTemplate = "Click here to view {0}\n{1}\n"; + + for (String metricToAnnotate : notification.getMetricsToAnnotate()) { + sb.append(MessageFormat.format(gusFeedLinkTemplate, "the annotated series for", + super.getMetricUrl(metricToAnnotate, context.getTriggerFiredTime()))); + } + sb.append(MessageFormat.format(gusFeedLinkTemplate, "alert definition.", super.getAlertUrl(notification.getAlert().getId()))); + return sb.toString(); + } + + private void postToGus(Set to, String feed) { + // So far works for only one group, will accept a set of string in future. + String groupId = to.toArray(new String[to.size()])[0]; + PostMethod gusPost = new PostMethod(_config.getValue(Property.POST_ENDPOINT.getName(), Property.POST_ENDPOINT.getDefaultValue())); + + try { + gusPost.setRequestHeader("Authorization", "Bearer " + generateAccessToken()); + String gusMessage = MessageFormat.format("{0}&subjectId={1}&text={2}", + _config.getValue(Property.POST_ENDPOINT.getName(), Property.POST_ENDPOINT.getDefaultValue()), groupId, + URLEncoder.encode(feed.toString(), "UTF-8")); + + gusPost.setRequestEntity(new StringRequestEntity(gusMessage, "application/x-www-form-urlencoded", null)); + HttpClient httpclient = getHttpClient(_config); + int respCode = httpclient.executeMethod(gusPost); + _logger.info("Gus message response code '{}'", respCode); + if (respCode == 201 || respCode == 204) { + _logger.info("Success - send to GUS group {}", groupId); + } else { + _logger.error("Failure - send to GUS group {}. Cause {}", groupId, gusPost.getResponseBodyAsString()); + } + } catch (Exception e) { + _logger.error("Throws Exception {} when posting to gus group {}", e, groupId); + } finally { + gusPost.releaseConnection(); + } + } + + private String generateAccessToken() { + // Set up an HTTP client that makes a connection to REST API. + HttpClient httpclient = getHttpClient(_config); + + // Send a post request to the OAuth URL. + PostMethod oauthPost = new PostMethod(_config.getValue(Property.GUS_ENDPOINT.getName(), Property.GUS_ENDPOINT.getDefaultValue())); + + try { + oauthPost.addParameter("grant_type", "password"); + oauthPost.addParameter("client_id", + URLEncoder.encode(_config.getValue(Property.GUS_CLIENT_ID.getName(), Property.GUS_CLIENT_ID.getDefaultValue()), UTF_8)); + oauthPost.addParameter("client_secret", + URLEncoder.encode(_config.getValue(Property.GUS_CLIENT_SECRET.getName(), Property.GUS_CLIENT_SECRET.getDefaultValue()), UTF_8)); + oauthPost.addParameter("username", _config.getValue(Property.ARGUS_GUS_USER.getName(), Property.ARGUS_GUS_USER.getDefaultValue())); + oauthPost.addParameter("password", _config.getValue(Property.ARGUS_GUS_PWD.getName(), Property.ARGUS_GUS_PWD.getDefaultValue())); + + int respCode = httpclient.executeMethod(oauthPost); + + _logger.info("Response code '{}'", respCode); + + // Check for success + if (respCode == 200) { + JsonObject authResponse = new Gson().fromJson(oauthPost.getResponseBodyAsString(), JsonObject.class); + String endpoint = authResponse.get("instance_url").getAsString(); + String token = authResponse.get("access_token").getAsString(); + + _logger.info("Success - getting access_token for endpoint '{}'", endpoint); + _logger.info("access_token '{}'", token); + return token; + } + else { + _logger.error("Failure - getting oauth2 token, check username/password: '{}'", oauthPost.getResponseBodyAsString()); + } + } catch (RuntimeException | IOException e) { + _logger.error("Failure - exception getting gus access_token {}", e); + } finally { + oauthPost.releaseConnection(); + } + return Strings.EMPTY; + } + + /** + * Get HttpClient with proper proxy and timeout settings. + * + * @param config The system configuration. Cannot be null. + * + * @return HttpClient + */ + public HttpClient getHttpClient(SystemConfiguration config) { + HttpClient httpclient = new HttpClient(theConnectionManager); + + // Wait for 2 seconds to get a connection from pool + httpclient.getParams().setParameter("http.connection-manager.timeout", 2000L); + + String host = config.getValue(Property.GUS_PROXY_HOST.getName(), Property.GUS_PROXY_HOST.getDefaultValue()); + + if (host != null && host.length() > 0) { + httpclient.getHostConfiguration().setProxy(host, + Integer.parseInt(config.getValue(Property.GUS_PROXY_PORT.getName(), Property.GUS_PROXY_PORT.getDefaultValue()))); + } + return httpclient; + } + + @Override + public Properties getNotifierProperties() { + Properties result = super.getNotifierProperties(); + + for( Property property : Property.values()) { + result.put(property.getName(), property.getDefaultValue()); + } + return result; + } + + public enum Property { + /** The GUS user name. */ + ARGUS_GUS_USER("notifier.property.alert.gus_user", "test@test.com"), + /** The GUS password. */ + ARGUS_GUS_PWD("notifier.property.alert.gus_pwd", "password"), + /** The GUS endpoint. */ + GUS_ENDPOINT("notifier.property.alert.gus_endpoint", "https://gus.test.com"), + /** The GUS client ID. */ + GUS_CLIENT_ID("notifier.property.alert.gus_client_id", "test123"), + /** The GUS client secret. */ + GUS_CLIENT_SECRET("notifier.property.alert.gus_client_secret", "password"), + /** The GUS post endpoint. */ + POST_ENDPOINT("notifier.property.alert.gus_post_endpoint", "https://gus.test.com"), + /** The GUS proxy host. */ + GUS_PROXY_HOST("notifier.property.proxy.host", ""), + /** The GUS port. */ + GUS_PROXY_PORT("notifier.property.proxy.port", ""); + + private final String _name; + private final String _defaultValue; + + private Property(String name, String defaultValue) { + _name = name; + _defaultValue = defaultValue; + } + + /** + * Returns the property name. + * + * @return The property name. + */ + public String getName() { + return _name; + } + + /** + * Returns the default value. + * + * @return The default value. + */ + public String getDefaultValue() { + return _defaultValue; + } + } } /* Copyright (c) 2016, Salesforce.com, Inc. All rights reserved. */ \ No newline at end of file diff --git a/ArgusCore/src/main/java/com/salesforce/dva/argus/service/metric/transform/GroupByTransform.java b/ArgusCore/src/main/java/com/salesforce/dva/argus/service/metric/transform/GroupByTransform.java new file mode 100644 index 000000000..df5ee2dcb --- /dev/null +++ b/ArgusCore/src/main/java/com/salesforce/dva/argus/service/metric/transform/GroupByTransform.java @@ -0,0 +1,82 @@ +package com.salesforce.dva.argus.service.metric.transform; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.salesforce.dva.argus.entity.Metric; +import com.salesforce.dva.argus.system.SystemAssert; + +public class GroupByTransform implements Transform { + + private TransformFactory _factory; + + public GroupByTransform(TransformFactory transformFactory) { + _factory = transformFactory; + } + + @Override + public List transform(List metrics) { + throw new UnsupportedOperationException("GroupBy Transform is supposed to be used with 2 constants: A regex match criteria and an aggregator function name."); + } + + @Override + public List transform(List metrics, List constants) { + SystemAssert.requireArgument(metrics != null, "Cannot transform null metrics"); + SystemAssert.requireArgument(constants != null && constants.size() >= 2, "Constants list cannot be null and its size must be 2 or more."); + + //Remove first constant which is the regex to group by. + Pattern pattern = Pattern.compile(constants.remove(0)); + //Remove second constant which is the function to perform on the grouped metrics. + String functionName = constants.remove(0); + + Map> groups = new HashMap<>(); + for(Metric metric : metrics) { + String identifier = metric.getIdentifier(); + Matcher matcher = pattern.matcher(identifier); + if(matcher.find()) { + String group = ""; + int i = 1; + while(i <= matcher.groupCount()) { + group += matcher.group(i++); + } + if(!groups.containsKey(group)) { + List m = new ArrayList<>(); + groups.put(group, m); + } + groups.get(group).add(metric); + } else { + if(!groups.containsKey(null)) { + List m = new ArrayList<>(); + groups.put(null, m); + } + groups.get(null).add(metric); + } + } + + Transform transform = _factory.getTransform(functionName); + List result = new ArrayList<>(); + for(Entry> entry : groups.entrySet()) { + List metricsInThisGroup = entry.getValue(); + List reducedMetrics = constants.isEmpty() ? transform.transform(metricsInThisGroup) : transform.transform(metricsInThisGroup, constants); + result.addAll(reducedMetrics); + } + + return result; + } + + @Override + public List transform(@SuppressWarnings("unchecked") List... metrics) { + throw new UnsupportedOperationException("Group By Transform doesn't need list of list!"); + } + + @Override + public String getResultScopeName() { + return TransformFactory.Function.GROUPBY.name(); + } + +} diff --git a/ArgusCore/src/main/java/com/salesforce/dva/argus/service/metric/transform/TransformFactory.java b/ArgusCore/src/main/java/com/salesforce/dva/argus/service/metric/transform/TransformFactory.java index 90945c4fc..b6f5713db 100644 --- a/ArgusCore/src/main/java/com/salesforce/dva/argus/service/metric/transform/TransformFactory.java +++ b/ArgusCore/src/main/java/com/salesforce/dva/argus/service/metric/transform/TransformFactory.java @@ -173,7 +173,7 @@ public Transform getTransform(String functionName) { case NORMALIZE_V: return new MetricZipperTransform(new DivideValueZipper()); case GROUPBY: - throw new UnsupportedOperationException(functionName); + return new GroupByTransform(this); case ANOMALY_DENSITY: return new AnomalyDetectionGaussianDensityTransform(); case ANOMALY_ZSCORE: diff --git a/ArgusCore/src/main/java/com/salesforce/dva/argus/service/schema/AsyncHbaseSchemaService.java b/ArgusCore/src/main/java/com/salesforce/dva/argus/service/schema/AsyncHbaseSchemaService.java index 523c48946..7c7da1b03 100644 --- a/ArgusCore/src/main/java/com/salesforce/dva/argus/service/schema/AsyncHbaseSchemaService.java +++ b/ArgusCore/src/main/java/com/salesforce/dva/argus/service/schema/AsyncHbaseSchemaService.java @@ -44,6 +44,7 @@ import com.salesforce.dva.argus.system.SystemException; import com.stumbleupon.async.Callback; import com.stumbleupon.async.Deferred; +import com.stumbleupon.async.TimeoutException; import org.apache.hadoop.hbase.util.Bytes; import org.hbase.async.CompareFilter.CompareOp; @@ -63,18 +64,18 @@ import java.nio.charset.Charset; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; -import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; /** - * HBASE implementation of the schema service. + * Implementation of the schema service using Asynchbase. * - * @author Tom Valine (tvaline@salesforce.com) + * @author Bhinav Sura (bhinav.sura@salesforce.com) */ @Singleton public class AsyncHbaseSchemaService extends DefaultService implements SchemaService { @@ -88,6 +89,8 @@ public class AsyncHbaseSchemaService extends DefaultService implements SchemaSer private static final byte[] CELL_VALUE = "1".getBytes(Charset.forName("UTF-8")); private static final char ROWKEY_SEPARATOR = ':'; private static final char[] WILDCARD_CHARSET = new char[] { '*', '?', '[', ']', '|' }; + + private static final long TIMEOUT = 2 * 60 * 1000; //~ Instance fields ****************************************************************************************************************************** @@ -314,7 +317,7 @@ public List get(MetricSchemaRecordQuery query, final int lim /** * Scans HBASE rows. * - * @author Tom Valine (tvaline@salesforce.com) + * @author Bhinav Sura (bhinav.sura@salesforce.com) */ final class ScannerCB implements Callback>> { @@ -364,12 +367,20 @@ public Object call(ArrayList> rows) throws Exception { } } } + new ScannerCB().scan(); + try { - return results.joinUninterruptibly(); - } catch (Exception e) { - throw new SystemException(e); - } + return results.join(TIMEOUT); + } catch (InterruptedException e) { + throw new SystemException("Interrupted while waiting to obtain results for query: " + query, e); + } catch (TimeoutException e) { + _logger.warn("Timed out while waiting to obtain results for query: {}. Will return an empty list.", query); + return Collections.emptyList(); + } catch (Exception e) { + throw new SystemException("Exception occured in getting results for query: " + query, e); + } + } @Override @@ -461,12 +472,20 @@ public Object call(ArrayList> rows) throws Exception { } } } + new ScannerCB().scan(); + try { - return new ArrayList(results.joinUninterruptibly()); - } catch (Exception e) { - throw new SystemException(e); - } + return new ArrayList<>(results.join(TIMEOUT)); + } catch (InterruptedException e) { + throw new SystemException("Interrupted while waiting to obtain results for query: " + query, e); + } catch (TimeoutException e) { + _logger.warn("Timed out while waiting to obtain results for query: {}. Will return an empty list.", query); + return Collections.emptyList(); + } catch (Exception e) { + throw new SystemException("Exception occured in getting results for query: " + query, e); + } + } @Override @@ -478,24 +497,23 @@ public void dispose() { Deferred deferred = _client.shutdown(); deferred.addCallback(new Callback() { - - @Override - public Void call(Object arg) throws Exception { - _logger.info("Shutdown of asynchbase client complete."); - return null; - } - }); + @Override + public Void call(Object arg) throws Exception { + _logger.info("Shutdown of asynchbase client complete."); + return null; + } + }); + deferred.addErrback(new Callback() { - - @Override - public Void call(Exception arg) throws Exception { - _logger.warn("Error occured while shutting down asynchbase client. Trying again..."); - _client.shutdown(); - return null; - } - }); + @Override + public Void call(Exception arg) throws Exception { + _logger.warn("Error occured while shutting down asynchbase client."); + return null; + } + }); + try { - deferred.joinUninterruptibly(); + deferred.join(); } catch (Exception e) { throw new SystemException("Exception while waiting for shutdown to complete.", e); } @@ -504,38 +522,34 @@ public Void call(Exception arg) throws Exception { private void _ensureTableWithColumnFamilyExists(byte[] table, byte[] family) { - final CountDownLatch latch = new CountDownLatch(1); - final AtomicBoolean fail = new AtomicBoolean(false); - _client.ensureTableFamilyExists(table, family).addCallbacks( - new Callback() { - - @Override - public Object call(Object arg) throws Exception { - latch.countDown(); - return null; - } - - }, - new Callback() { - - @Override - public Object call(Object arg) throws Exception { - fail.set(true); - latch.countDown(); - return null; - } - } - ); + final AtomicBoolean fail = new AtomicBoolean(true); + + Deferred deferred = _client.ensureTableFamilyExists(table, family); + + deferred.addCallback(new Callback() { + @Override + public Void call(Object arg) throws Exception { + fail.set(false); + return null; + } + }); + + deferred.addErrback(new Callback() { + @Override + public Void call(Exception arg) throws Exception { + _logger.error("Table {} or family {} does not exist. Please create the appropriate table.", Bytes.toString(table), Bytes.toString(family)); + return null; + } + }); try { - latch.await(); + deferred.join(TIMEOUT); } catch (InterruptedException e) { - throw new SystemException("Interrupted", e); - } + throw new SystemException("Interrupted while waiting to ensure schema tables exist.", e); + } catch (Exception e) { + _logger.error("Exception occured while waiting to ensure table {} with family {} exists", Bytes.toString(table), Bytes.toString(family)); + } - if(fail.get()) { - throw new SystemException("Table or Column Family doesn't exist."); - } } private void _putWithoutTag(Metric metric, String tableName) { diff --git a/ArgusCore/src/main/javacc/MetricReader.jj b/ArgusCore/src/main/javacc/MetricReader.jj index 31c29825b..c775f4f3a 100644 --- a/ArgusCore/src/main/javacc/MetricReader.jj +++ b/ArgusCore/src/main/javacc/MetricReader.jj @@ -134,8 +134,10 @@ TOKEN : { < #SQUARE_OPEN : "[" > } TOKEN : { < #SQUARE_CLOSE : "]" > } TOKEN : { < #OR : "|" > } TOKEN : { < #DOLLAR : "$" > } +TOKEN : { < #POUND : "#" > } TOKEN : { < #NOT : "!" > } TOKEN : { < #TIME_UNIT : "s" | "m" | "h" | "d" > } +TOKEN : { < #ANYTHING : ~["#"] > } TOKEN : { < IDENTITY : "IDENTITY" > } TOKEN : { < SUM : "SUM" > } @@ -207,7 +209,8 @@ TOKEN : { < NAMESPACE : > } TOKEN : { < SCOPE : > } TOKEN : { < METRIC : > } TOKEN : { < TAGS : ()* > } -TOKEN : { < CONSTANT : ()+ > } +//TOKEN : { < CONSTANT : ()+ > } +TOKEN : { < CONSTANT : ()+ > } boolean isValidExpression(String expression) : {} diff --git a/ArgusCore/src/test/java/com/salesforce/dva/argus/service/metric/transform/GroupByTransformTest.java b/ArgusCore/src/test/java/com/salesforce/dva/argus/service/metric/transform/GroupByTransformTest.java new file mode 100644 index 000000000..d35ac58ae --- /dev/null +++ b/ArgusCore/src/test/java/com/salesforce/dva/argus/service/metric/transform/GroupByTransformTest.java @@ -0,0 +1,330 @@ +package com.salesforce.dva.argus.service.metric.transform; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; + +import com.salesforce.dva.argus.AbstractTest; +import com.salesforce.dva.argus.entity.Metric; + +public class GroupByTransformTest extends AbstractTest { + + @Test + public void testGroupByPodOnly() { + + GroupByTransform transform = new GroupByTransform(new TransformFactory(system.getServiceFactory().getTSDBService())); + + Map datapoints = new HashMap(); + datapoints.put(1000L, "1"); + + List metrics = new ArrayList<>(); + + Metric metric1 = new Metric("system.WAS.na1", "metric1"); + metric1.setDatapoints(datapoints); + + Metric metric2 = new Metric("system.WAS.na2", "metric1"); + metric2.setDatapoints(datapoints); + + Metric metric3 = new Metric("system.CHI.na1", "metric1"); + metric3.setDatapoints(datapoints); + + Metric metric4 = new Metric("system.CHI.na2", "metric1"); + metric4.setDatapoints(datapoints); + + metrics.add(metric1); + metrics.add(metric2); + metrics.add(metric3); + metrics.add(metric4); + + List constants = new ArrayList<>(); + constants.add("system\\.([A-Z]+)\\.na."); + constants.add("SUM"); + + List result = transform.transform(metrics, constants); + assertTrue(result.size() == 2); + for(Metric r : result) { + assertEquals("2.0", r.getDatapoints().get(1000L)); + } + } + + @Test + public void testGroupByDCAndPodPrefix() { + + GroupByTransform transform = new GroupByTransform(new TransformFactory(system.getServiceFactory().getTSDBService())); + + Map datapoints = new HashMap(); + datapoints.put(1000L, "1"); + + List metrics = new ArrayList<>(); + + Metric metric1 = new Metric("system.WAS.SP1.na1", "metric1"); + metric1.setDatapoints(datapoints); + + Metric metric2 = new Metric("system.WAS.SP1.na2", "metric1"); + metric2.setDatapoints(datapoints); + + Metric metric3 = new Metric("system.WAS.SP1.cs1", "metric1"); + metric3.setDatapoints(datapoints); + + Metric metric4 = new Metric("system.WAS.SP1.cs2", "metric1"); + metric4.setDatapoints(datapoints); + + Metric metric5 = new Metric("system.CHI.SP1.na1", "metric1"); + metric5.setDatapoints(datapoints); + + Metric metric6 = new Metric("system.CHI.SP1.na2", "metric1"); + metric6.setDatapoints(datapoints); + + Metric metric7 = new Metric("system.CHI.SP1.cs1", "metric1"); + metric7.setDatapoints(datapoints); + + Metric metric8 = new Metric("system.CHI.SP1.cs2", "metric1"); + metric8.setDatapoints(datapoints); + + metrics.add(metric1); + metrics.add(metric2); + metrics.add(metric3); + metrics.add(metric4); + metrics.add(metric5); + metrics.add(metric6); + metrics.add(metric7); + metrics.add(metric8); + + List constants = new ArrayList<>(); + constants.add("system\\.([A-Z]+)\\.SP.\\.([a-z]+)."); + constants.add("DIVIDE"); + + List result = transform.transform(metrics, constants); + assertTrue(result.size() == 4); + for(Metric r : result) { + assertEquals("1.0", r.getDatapoints().get(1000L)); + } + } + + @Test + public void testGroupByDCAndPodNumber() { + + GroupByTransform transform = new GroupByTransform(new TransformFactory(system.getServiceFactory().getTSDBService())); + + Map datapoints = new HashMap(); + datapoints.put(1000L, "1"); + + List metrics = new ArrayList<>(); + + Metric metric1 = new Metric("system.WAS.SP1.na1", "metric1"); + metric1.setDatapoints(datapoints); + + Metric metric2 = new Metric("system.WAS.SP1.na2", "metric1"); + metric2.setDatapoints(datapoints); + + Metric metric3 = new Metric("system.WAS.SP1.cs1", "metric2"); + metric3.setDatapoints(datapoints); + + Metric metric4 = new Metric("system.WAS.SP1.cs2", "metric2"); + metric4.setDatapoints(datapoints); + + Metric metric5 = new Metric("system.CHI.SP1.na1", "metric1"); + metric5.setDatapoints(datapoints); + + Metric metric6 = new Metric("system.CHI.SP1.na2", "metric1"); + metric6.setDatapoints(datapoints); + + Metric metric7 = new Metric("system.CHI.SP1.cs1", "metric2"); + metric7.setDatapoints(datapoints); + + Metric metric8 = new Metric("system.CHI.SP1.cs2", "metric2"); + metric8.setDatapoints(datapoints); + + metrics.add(metric1); + metrics.add(metric2); + metrics.add(metric3); + metrics.add(metric4); + metrics.add(metric5); + metrics.add(metric6); + metrics.add(metric7); + metrics.add(metric8); + + List constants = new ArrayList<>(); + constants.add("system\\.([A-Z]+)\\.SP.\\.[a-z][a-z][0-9]:([a-z0-9]+)."); + constants.add("SUM"); + + List result = transform.transform(metrics, constants); + assertTrue(result.size() == 4); + + } + + @Test + public void testWeightedAvgUsingGroupBy() { + + GroupByTransform transform = new GroupByTransform(new TransformFactory(system.getServiceFactory().getTSDBService())); + + Map datapoints = new HashMap(); + datapoints.put(1000L, "1"); + + List metrics = new ArrayList<>(); + + Metric metric1 = new Metric("system.CHI.SP1.na10", "latency"); + metric1.setTag("device", "na10-app1-1-chi.ops.sfdc.net"); + metric1.setDatapoints(datapoints); + + Metric metric2 = new Metric("system.CHI.SP1.na10", "latency"); + metric2.setTag("device", "na10-app1-2-chi.ops.sfdc.net"); + metric2.setDatapoints(datapoints); + + Metric metric3 = new Metric("system.CHI.SP1.na10", "latency"); + metric3.setTag("device", "na10-app2-1-chi.ops.sfdc.net"); + metric3.setDatapoints(datapoints); + + Metric metric4 = new Metric("system.CHI.SP1.na10", "latency"); + metric4.setTag("device", "na10-app2-2-chi.ops.sfdc.net"); + metric4.setDatapoints(datapoints); + + + Metric metric5 = new Metric("system.CHI.SP1.na10", "count"); + metric5.setTag("device", "na10-app1-1-chi.ops.sfdc.net"); + metric5.setDatapoints(datapoints); + + Metric metric6 = new Metric("system.CHI.SP1.na10", "count"); + metric6.setTag("device", "na10-app1-2-chi.ops.sfdc.net"); + metric6.setDatapoints(datapoints); + + Metric metric7 = new Metric("system.CHI.SP1.na10", "count"); + metric7.setTag("device", "na10-app2-1-chi.ops.sfdc.net"); + metric7.setDatapoints(datapoints); + + Metric metric8 = new Metric("system.CHI.SP1.na10", "count"); + metric8.setTag("device", "na10-app2-2-chi.ops.sfdc.net"); + metric8.setDatapoints(datapoints); + + metrics.add(metric1); + metrics.add(metric2); + metrics.add(metric3); + metrics.add(metric4); + metrics.add(metric5); + metrics.add(metric6); + metrics.add(metric7); + metrics.add(metric8); + + List constants = new ArrayList<>(); + constants.add("(app.*-chi)"); + constants.add("SCALE"); + + List result = transform.transform(metrics, constants); + assertTrue(result.size() == 4); + } + + @Test + public void testGroupByPod() { + + GroupByTransform transform = new GroupByTransform(new TransformFactory(system.getServiceFactory().getTSDBService())); + + Map datapoints = new HashMap(); + datapoints.put(1000L, "1"); + + List metrics = new ArrayList<>(); + + Metric metric1 = new Metric("system.CHI.SP1.na1", "latency"); + metric1.setTag("device", "na1-app1-1-chi.ops.sfdc.net"); + metric1.setDatapoints(datapoints); + + Metric metric11 = new Metric("system.CHI.SP1.na1", "latency"); + metric11.setTag("device", "na1-app1-2-chi.ops.sfdc.net"); + metric11.setDatapoints(datapoints); + + + Metric metric2 = new Metric("system.CHI.SP1.na2", "latency"); + metric2.setTag("device", "na2-app1-1-chi.ops.sfdc.net"); + metric2.setDatapoints(datapoints); + + Metric metric21 = new Metric("system.CHI.SP1.na2", "latency"); + metric21.setTag("device", "na2-app1-2-chi.ops.sfdc.net"); + metric21.setDatapoints(datapoints); + + Metric metric3 = new Metric("system.CHI.SP1.na3", "latency"); + metric3.setTag("device", "na3-app1-1-chi.ops.sfdc.net"); + metric3.setDatapoints(datapoints); + + Metric metric31 = new Metric("system.CHI.SP1.na3", "latency"); + metric31.setTag("device", "na3-app1-2-chi.ops.sfdc.net"); + metric31.setDatapoints(datapoints); + + metrics.add(metric1); + metrics.add(metric11); + metrics.add(metric2); + metrics.add(metric21); + metrics.add(metric3); + metrics.add(metric31); + + + List constants = new ArrayList<>(); + constants.add("(system\\.CHI\\.SP1\\..*:latency)"); + constants.add("SUM"); + + List result = transform.transform(metrics, constants); + assertTrue(result.size() == 3); + for(Metric r : result) { + assertEquals("2.0", r.getDatapoints().get(1000L)); + } + } + + @Test + public void testGroupByWithFunctionTakingConstants() { + + GroupByTransform transform = new GroupByTransform(new TransformFactory(system.getServiceFactory().getTSDBService())); + + Map datapoints = new HashMap(); + datapoints.put(1000L, "1"); + + List metrics = new ArrayList<>(); + + Metric metric1 = new Metric("system.CHI.SP1.na1", "latency"); + metric1.setTag("device", "na1-app1-1-chi.ops.sfdc.net"); + metric1.setDatapoints(datapoints); + + Metric metric11 = new Metric("system.CHI.SP1.na1", "latency"); + metric11.setTag("device", "na1-app1-2-chi.ops.sfdc.net"); + metric11.setDatapoints(datapoints); + + + Metric metric2 = new Metric("system.CHI.SP1.na2", "latency"); + metric2.setTag("device", "na2-app1-1-chi.ops.sfdc.net"); + metric2.setDatapoints(datapoints); + + Metric metric21 = new Metric("system.CHI.SP1.na2", "latency"); + metric21.setTag("device", "na2-app1-2-chi.ops.sfdc.net"); + metric21.setDatapoints(datapoints); + + Metric metric3 = new Metric("system.CHI.SP1.na3", "latency"); + metric3.setTag("device", "na3-app1-1-chi.ops.sfdc.net"); + metric3.setDatapoints(datapoints); + + Metric metric31 = new Metric("system.CHI.SP1.na3", "latency"); + metric31.setTag("device", "na3-app1-2-chi.ops.sfdc.net"); + metric31.setDatapoints(datapoints); + + metrics.add(metric1); + metrics.add(metric11); + metrics.add(metric2); + metrics.add(metric21); + metrics.add(metric3); + metrics.add(metric31); + + + List constants = new ArrayList<>(); + constants.add("(system\\.CHI\\.SP1\\..*:latency)"); + constants.add("PERCENTILE"); + constants.add("90"); + + List result = transform.transform(metrics, constants); + assertTrue(result.size() == 3); + for(Metric r : result) { + assertEquals("1", r.getDatapoints().get(1000L)); + } + } + +} diff --git a/ArgusCore/src/test/resources/com/salesforce/dva/argus/service/metric/MetricReaderTest.testFunctionsWithConstant.properties b/ArgusCore/src/test/resources/com/salesforce/dva/argus/service/metric/MetricReaderTest.testFunctionsWithConstant.properties index 46cfbfdf7..e8e1f966b 100644 --- a/ArgusCore/src/test/resources/com/salesforce/dva/argus/service/metric/MetricReaderTest.testFunctionsWithConstant.properties +++ b/ArgusCore/src/test/resources/com/salesforce/dva/argus/service/metric/MetricReaderTest.testFunctionsWithConstant.properties @@ -1,142 +1,145 @@ -func-with-str-constant=AVERAGEBELOW(-1d:na1:app_record.count:avg, $abc) -func-with-int-constant=AVERAGEBELOW(-1d:na1:app_record.count:avg, $200) -func-with-int-constant1=AVERAGEBELOW(-1d:na1:app_record.count:avg, $2) -func-with-float-constant=AVERAGEBELOW(-1d:na1:app_record.count:avg, $200.45) -func-of-func-with-constant1=AVERAGEBELOW(MULTIPLY(-1d:na1:app_record.count:avg,-1d:na1:app_record.count:avg), $10) -func-of-func-with-constant2=MULTIPLY(-1d:na1:app_record.count:avg, AVERAGEBELOW(-1d:na1:app_record.count:avg, $10)) -func-of-func-with-constant3=MULTIPLY(AVERAGEBELOW(-1d:na1:app_record.count:avg, $10.0), -1d:na1:app_record.count:avg) -func-with-multiple-exp-and-constant=AVERAGEBELOW(-1d:na1:app_record.count:avg,-1d:na1:app_record.count:avg, $10) -func-of-funcwithconst-and-funcwithconst=MULTIPLY(AVERAGEBELOW(-1d:na1:app_record.count:avg, $15), AVERAGEBELOW(-1d:na1:app_record.count:avg, $10)) -func-with-multiple-constants=AVERAGEBELOW(-1d:na1:app_record.count:avg, $5.0, $1min) -func-with-multiple-exp-and-multiple-constants=AVERAGEBELOW(-1d:na1:app_record.count:avg,-1d:na1:app_record.count:avg, $10, $5min) - -fun-relative-timestamps-without-endTs-sum=SUM(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-sum=SUM(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-sum=SUM(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-sum=SUM(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-diff=DIFF(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-diff=DIFF(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-diff=DIFF(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-diff=DIFF(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-scale=SCALE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-scale=SCALE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-scale=SCALE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-scale=SCALE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-divide=DIVIDE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-divide=DIVIDE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-divide=DIVIDE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-divide=DIVIDE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-percentile=PERCENTILE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $30, $null) -fun-startTs-absolute-endTs-relative-percentile=PERCENTILE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $30, $null) -fun-all-fields-wildcardtags1-percentile=PERCENTILE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $30, $10) -fun-all-fields-wildcardtags2-percentile=PERCENTILE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $30, $10) - -fun-relative-timestamps-without-endTs-propagate=PROPAGATE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-propagate=PROPAGATE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-propagate=PROPAGATE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-propagate=PROPAGATE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-moving=MOVING(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-moving=MOVING(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-moving=MOVING(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-moving=MOVING(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-above=ABOVE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-above=ABOVE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-above=ABOVE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-above=ABOVE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-below=BELOW(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-below=BELOW(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-below=BELOW(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-below=BELOW(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-highest=HIGHEST(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-highest=HIGHEST(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-highest=HIGHEST(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-highest=HIGHEST(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-lowest=LOWEST(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-lowest=LOWEST(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-lowest=LOWEST(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-lowest=LOWEST(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-sort=SORT(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-sort=SORT(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-sort=SORT(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-sort=SORT(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) -bug-example-sort=SORT(-1d:argus.jvm:file.descriptor.open{host=*}:max:6h-max,$3,$name,$descending) - -fun-relative-timestamps-without-endTs-downsample=DOWNSAMPLE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-downsample=DOWNSAMPLE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-downsample=DOWNSAMPLE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-downsample=DOWNSAMPLE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-cullabove=CULL_ABOVE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-cullabove=CULL_ABOVE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-cullabove=CULL_ABOVE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-cullabove=CULL_ABOVE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-cullbelow=CULL_BELOW(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-cullbelow=CULL_BELOW(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-cullbelow=CULL_BELOW(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-cullbelow=CULL_BELOW(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-log=LOG(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-log=LOG(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-log=LOG(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-log=LOG(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-limit=LIMIT(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-limit=LIMIT(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-limit=LIMIT(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-limit=LIMIT(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-shift=SHIFT(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-shift=SHIFT(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-shift=SHIFT(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-shift=SHIFT(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-derivative=DERIVATIVE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-derivative=DERIVATIVE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-derivative=DERIVATIVE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-derivative=DERIVATIVE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-normalize=NORMALIZE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-normalize=NORMALIZE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-normalize=NORMALIZE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-normalize=NORMALIZE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-fill=FILL(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-fill=FILL(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-fill=FILL(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-fill=FILL(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-deviation=DEVIATION(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-deviation=DEVIATION(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-deviation=DEVIATION(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-deviation=DEVIATION(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-alias=ALIAS(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-alias=ALIAS(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-alias=ALIAS(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-alias=ALIAS(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-include=INCLUDE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-include=INCLUDE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-include=INCLUDE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-include=INCLUDE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-exclude=EXCLUDE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-startTs-absolute-endTs-relative-exclude=EXCLUDE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $null) -fun-all-fields-wildcardtags1-exclude=EXCLUDE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10) -fun-all-fields-wildcardtags2-exclude=EXCLUDE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10) - -fun-relative-timestamps-without-endTs-consective=CONSECUTIVE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $10s,$10s) -fun-startTs-absolute-endTs-relative-consective=CONSECUTIVE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, $10s,$10s) -fun-all-fields-wildcardtags1-consective=CONSECUTIVE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, $10s,$10s) -fun-all-fields-wildcardtags2-consective=CONSECUTIVE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, $10s,$10s) \ No newline at end of file +func=FILL(SUM(DIFF(SUM(CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-ASG-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-CHI-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-CHI-SP2-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-CHI-SP3-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-CHI-SP4-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-DFW-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-DFW-SP2-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-FRF-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-LON-SP9-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-PAR-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-PHX-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-PHX-SP2-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-TYO-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-WAS-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-WAS-SP2-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-WAS-SP3-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-WAS-SP4-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#)),SUM(CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-ASG-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-CHI-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-CHI-SP2-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-CHI-SP3-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-CHI-SP4-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-DFW-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-DFW-SP2-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-FRF-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-LON-SP9-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-PAR-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-PHX-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-PHX-SP2-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-TYO-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-WAS-SP1-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-WAS-SP2-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-WAS-SP3-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#),CULL_BELOW(CULL_ABOVE(PROPAGATE(SCALE(-1h:ajna-auditor.SFZ.AGG.none:AJNA-WAS-SP4-SFZ.all_metrics.latency.max{device=ajna-mmcnsmr8-2-sfz}:max:20m-max,#0.001#),#1m#),#1800#,#value#),#0.001#,#value#))),#1#),#1m#,#0m#,#0#) +func-with-str-constant=AVERAGEBELOW(-1d:na1:app_record.count:avg, #abc#) +func-with-regex-constant=AVERAGEBELOW(-1d:na1:app_record.count:avg, #(app1-1\\.ops\\.sfdc\\.net)#) +func-with-int-constant=AVERAGEBELOW(-1d:na1:app_record.count:avg, #200#) +func-with-int-constant1=AVERAGEBELOW(-1d:na1:app_record.count:avg, #2#) +func-with-float-constant=AVERAGEBELOW(-1d:na1:app_record.count:avg, #200.45#) +func-of-func-with-constant1=AVERAGEBELOW(MULTIPLY(-1d:na1:app_record.count:avg,-1d:na1:app_record.count:avg), #10#) +func-of-func-with-constant2=MULTIPLY(-1d:na1:app_record.count:avg, AVERAGEBELOW(-1d:na1:app_record.count:avg, #10#)) +func-of-func-with-constant3=MULTIPLY(AVERAGEBELOW(-1d:na1:app_record.count:avg, #10.0#), -1d:na1:app_record.count:avg) +func-with-multiple-exp-and-constant=AVERAGEBELOW(-1d:na1:app_record.count:avg,-1d:na1:app_record.count:avg, #10#) +func-of-funcwithconst-and-funcwithconst=MULTIPLY(AVERAGEBELOW(-1d:na1:app_record.count:avg, #15#), AVERAGEBELOW(-1d:na1:app_record.count:avg, #10#)) +func-with-multiple-constants=AVERAGEBELOW(-1d:na1:app_record.count:avg, #5.0#, #1min#) +func-with-multiple-exp-and-multiple-constants=AVERAGEBELOW(-1d:na1:app_record.count:avg,-1d:na1:app_record.count:avg, #10#, #5min#) + +fun-relative-timestamps-without-endTs-sum=SUM(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-sum=SUM(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-sum=SUM(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-sum=SUM(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-diff=DIFF(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-diff=DIFF(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-diff=DIFF(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-diff=DIFF(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-scale=SCALE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-scale=SCALE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-scale=SCALE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-scale=SCALE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-divide=DIVIDE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-divide=DIVIDE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-divide=DIVIDE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-divide=DIVIDE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-percentile=PERCENTILE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #30#, #null#) +fun-startTs-absolute-endTs-relative-percentile=PERCENTILE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #30#, #null#) +fun-all-fields-wildcardtags1-percentile=PERCENTILE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #30#, #10#) +fun-all-fields-wildcardtags2-percentile=PERCENTILE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #30#, #10#) + +fun-relative-timestamps-without-endTs-propagate=PROPAGATE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-propagate=PROPAGATE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-propagate=PROPAGATE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-propagate=PROPAGATE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-moving=MOVING(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-moving=MOVING(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-moving=MOVING(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-moving=MOVING(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-above=ABOVE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-above=ABOVE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-above=ABOVE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-above=ABOVE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-below=BELOW(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-below=BELOW(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-below=BELOW(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-below=BELOW(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-highest=HIGHEST(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-highest=HIGHEST(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-highest=HIGHEST(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-highest=HIGHEST(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-lowest=LOWEST(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-lowest=LOWEST(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-lowest=LOWEST(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-lowest=LOWEST(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-sort=SORT(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-sort=SORT(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-sort=SORT(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-sort=SORT(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) +bug-example-sort=SORT(-1d:argus.jvm:file.descriptor.open{host=*}:max:6h-max,#3#,#name#,#descending#) + +fun-relative-timestamps-without-endTs-downsample=DOWNSAMPLE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-downsample=DOWNSAMPLE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-downsample=DOWNSAMPLE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-downsample=DOWNSAMPLE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-cullabove=CULL_ABOVE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-cullabove=CULL_ABOVE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-cullabove=CULL_ABOVE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-cullabove=CULL_ABOVE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-cullbelow=CULL_BELOW(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-cullbelow=CULL_BELOW(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-cullbelow=CULL_BELOW(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-cullbelow=CULL_BELOW(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-log=LOG(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-log=LOG(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-log=LOG(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-log=LOG(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-limit=LIMIT(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-limit=LIMIT(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-limit=LIMIT(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-limit=LIMIT(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-shift=SHIFT(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-shift=SHIFT(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-shift=SHIFT(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-shift=SHIFT(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-derivative=DERIVATIVE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-derivative=DERIVATIVE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-derivative=DERIVATIVE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-derivative=DERIVATIVE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-normalize=NORMALIZE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-normalize=NORMALIZE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-normalize=NORMALIZE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-normalize=NORMALIZE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-fill=FILL(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-fill=FILL(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-fill=FILL(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-fill=FILL(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-deviation=DEVIATION(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-deviation=DEVIATION(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-deviation=DEVIATION(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-deviation=DEVIATION(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-alias=ALIAS(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-alias=ALIAS(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-alias=ALIAS(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-alias=ALIAS(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-alias=ALIAS(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #[345,34|sd4f]#) + +fun-relative-timestamps-without-endTs-include=INCLUDE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-include=INCLUDE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-include=INCLUDE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-include=INCLUDE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-exclude=EXCLUDE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-startTs-absolute-endTs-relative-exclude=EXCLUDE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #null#) +fun-all-fields-wildcardtags1-exclude=EXCLUDE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10#) +fun-all-fields-wildcardtags2-exclude=EXCLUDE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10#) + +fun-relative-timestamps-without-endTs-consective=CONSECUTIVE(-20h:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #10s#,#10s#) +fun-startTs-absolute-endTs-relative-consective=CONSECUTIVE(123000:-1m:na1:app_record.count{tagk=tagv}:avg:15m-avg,123000:234000:na1:app_record.count{tak=tagv}:avg, #10s#,#10s#) +fun-all-fields-wildcardtags1-consective=CONSECUTIVE(123000:234000:na1:app_record.count{tagk=*}:avg:15m-avg, #10s#,#10s#) +fun-all-fields-wildcardtags2-consective=CONSECUTIVE(123000:234000:na1:app_record.count{tagk=tagv1|tagv2}:avg:15m-avg, #10s#,#10s#) \ No newline at end of file diff --git a/ArgusWeb/app/js/controllers/alertsDetail.js b/ArgusWeb/app/js/controllers/alertsDetail.js index 07ae9c3b0..f41f51f71 100644 --- a/ArgusWeb/app/js/controllers/alertsDetail.js +++ b/ArgusWeb/app/js/controllers/alertsDetail.js @@ -131,7 +131,7 @@ angular.module('argus.controllers.alerts.detail', ['ngResource']) notifierName: "com.salesforce.dva.argus.service.alert.notifier.EmailNotifier", subscriptions: [], metricsToAnnotate: [], - cooldownPeriod: 3600000, + cooldownPeriod: 0, alertId: $scope.alert.id }; diff --git a/ArgusWebServices/src/main/java/com/salesforce/dva/argus/ws/resources/DiscoveryResources.java b/ArgusWebServices/src/main/java/com/salesforce/dva/argus/ws/resources/DiscoveryResources.java index a70e3368d..bf0984150 100644 --- a/ArgusWebServices/src/main/java/com/salesforce/dva/argus/ws/resources/DiscoveryResources.java +++ b/ArgusWebServices/src/main/java/com/salesforce/dva/argus/ws/resources/DiscoveryResources.java @@ -38,6 +38,7 @@ import com.salesforce.dva.argus.ws.annotation.Description; import java.util.List; import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; @@ -80,13 +81,13 @@ public class DiscoveryResources extends AbstractResource { @Path("/metrics/schemarecords") @Description("Discover metric schema records. If type is specified, then records of that particular type are returned.") public List getRecords(@Context HttpServletRequest req, - @QueryParam("namespace") final String namespaceRegex, + @DefaultValue("*") @QueryParam("namespace") final String namespaceRegex, @QueryParam("scope") final String scopeRegex, @QueryParam("metric") final String metricRegex, - @QueryParam("tagk") final String tagkRegex, - @QueryParam("tagv") final String tagvRegex, - @QueryParam("limit") final int limit, - @QueryParam("page") final int page, + @DefaultValue("*") @QueryParam("tagk") final String tagkRegex, + @DefaultValue("*") @QueryParam("tagv") final String tagvRegex, + @DefaultValue("10") @QueryParam("limit") final int limit, + @DefaultValue("1") @QueryParam("page") final int page, @QueryParam("type") String type) { PrincipalUser remoteUser = validateAndGetOwner(req, null); @@ -103,18 +104,6 @@ public List getRecords(@Context HttpServletRequest req, return records; } } - - /* - * @GET @Produces(MediaType.APPLICATION_JSON) @Path("/metrics/queries") @Description("Discover wildcard queries.") public List - * matchQueries(@Context HttpServletRequest req, @QueryParam("scope") final String scopeRegex, @QueryParam("metric") final String - * metricRegex) { - * - * PrincipalUser remoteUser = validateAndGetOwner(req, null); - * - * validateResourceAuthorization(req, remoteUser, remoteUser); Map tags = new HashMap(); tags.put("device", "*"); - * MetricQuery query = new MetricQuery(scopeRegex, metricRegex, tags, 1L, 2L); List queries = - * _discoveryService.getMatchingQueries(query); List queryStrs = new ArrayList(queries.size()); for(MetricQuery mq : queries) { - * queryStrs.add(mq.toString()); } return queryStrs; } - */ + } /* Copyright (c) 2016, Salesforce.com, Inc. All rights reserved. */