diff --git a/pom.xml b/pom.xml
index 360a5e44..87fce7fd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
net.iponweb.disthene.reader
disthene-reader
jar
- 0.2.45
+ 0.2.46
disthene-reader
http://maven.apache.org
diff --git a/src/main/java/net/iponweb/disthene/reader/graphite/functions/ExcludeFunction.java b/src/main/java/net/iponweb/disthene/reader/graphite/functions/ExcludeFunction.java
new file mode 100644
index 00000000..20208bf0
--- /dev/null
+++ b/src/main/java/net/iponweb/disthene/reader/graphite/functions/ExcludeFunction.java
@@ -0,0 +1,60 @@
+package net.iponweb.disthene.reader.graphite.functions;
+
+import net.iponweb.disthene.reader.beans.TimeSeries;
+import net.iponweb.disthene.reader.beans.TimeSeriesOption;
+import net.iponweb.disthene.reader.exceptions.EvaluationException;
+import net.iponweb.disthene.reader.exceptions.InvalidArgumentException;
+import net.iponweb.disthene.reader.exceptions.TimeSeriesNotAlignedException;
+import net.iponweb.disthene.reader.graph.ColorTable;
+import net.iponweb.disthene.reader.graphite.Target;
+import net.iponweb.disthene.reader.graphite.evaluation.TargetEvaluator;
+import net.iponweb.disthene.reader.utils.TimeSeriesUtils;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Andrei Ivanov
+ */
+public class ExcludeFunction extends DistheneFunction {
+
+ public ExcludeFunction(String text) {
+ super(text, "exclude");
+ }
+
+ @Override
+ public List evaluate(TargetEvaluator evaluator) throws EvaluationException {
+ List processedArguments = new ArrayList<>();
+ processedArguments.addAll(evaluator.eval((Target) arguments.get(0)));
+
+ if (processedArguments.size() == 0) return new ArrayList<>();
+
+ if (!TimeSeriesUtils.checkAlignment(processedArguments)) {
+ throw new TimeSeriesNotAlignedException();
+ }
+
+ String regex = (String) arguments.get(1);
+ Pattern pattern = Pattern.compile(regex);
+
+ List result = new ArrayList<>();
+
+ for (TimeSeries ts : processedArguments) {
+ Matcher matcher = pattern.matcher(ts.getName());
+ if (!matcher.find()) {
+ result.add(ts);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public void checkArguments() throws InvalidArgumentException {
+ if (arguments.size() != 2) throw new InvalidArgumentException("exclude: number of arguments is " + arguments.size() + ". Must be two.");
+ if (!(arguments.get(0) instanceof Target)) throw new InvalidArgumentException("exclude: argument is " + arguments.get(0).getClass().getName() + ". Must be series");
+ if (!(arguments.get(1) instanceof String)) throw new InvalidArgumentException("exclude: argument is " + arguments.get(1).getClass().getName() + ". Must be a string");
+ }
+}
diff --git a/src/main/java/net/iponweb/disthene/reader/graphite/functions/GrepFunction.java b/src/main/java/net/iponweb/disthene/reader/graphite/functions/GrepFunction.java
new file mode 100644
index 00000000..2af715c9
--- /dev/null
+++ b/src/main/java/net/iponweb/disthene/reader/graphite/functions/GrepFunction.java
@@ -0,0 +1,57 @@
+package net.iponweb.disthene.reader.graphite.functions;
+
+import net.iponweb.disthene.reader.beans.TimeSeries;
+import net.iponweb.disthene.reader.exceptions.EvaluationException;
+import net.iponweb.disthene.reader.exceptions.InvalidArgumentException;
+import net.iponweb.disthene.reader.exceptions.TimeSeriesNotAlignedException;
+import net.iponweb.disthene.reader.graphite.Target;
+import net.iponweb.disthene.reader.graphite.evaluation.TargetEvaluator;
+import net.iponweb.disthene.reader.utils.TimeSeriesUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Andrei Ivanov
+ */
+public class GrepFunction extends DistheneFunction {
+
+ public GrepFunction(String text) {
+ super(text, "grep");
+ }
+
+ @Override
+ public List evaluate(TargetEvaluator evaluator) throws EvaluationException {
+ List processedArguments = new ArrayList<>();
+ processedArguments.addAll(evaluator.eval((Target) arguments.get(0)));
+
+ if (processedArguments.size() == 0) return new ArrayList<>();
+
+ if (!TimeSeriesUtils.checkAlignment(processedArguments)) {
+ throw new TimeSeriesNotAlignedException();
+ }
+
+ String regex = (String) arguments.get(1);
+ Pattern pattern = Pattern.compile(regex);
+
+ List result = new ArrayList<>();
+
+ for (TimeSeries ts : processedArguments) {
+ Matcher matcher = pattern.matcher(ts.getName());
+ if (matcher.find()) {
+ result.add(ts);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public void checkArguments() throws InvalidArgumentException {
+ if (arguments.size() != 2) throw new InvalidArgumentException("grep: number of arguments is " + arguments.size() + ". Must be two.");
+ if (!(arguments.get(0) instanceof Target)) throw new InvalidArgumentException("grep: argument is " + arguments.get(0).getClass().getName() + ". Must be series");
+ if (!(arguments.get(1) instanceof String)) throw new InvalidArgumentException("grep: argument is " + arguments.get(1).getClass().getName() + ". Must be a string");
+ }
+}
diff --git a/src/main/java/net/iponweb/disthene/reader/graphite/functions/registry/FunctionRegistry.java b/src/main/java/net/iponweb/disthene/reader/graphite/functions/registry/FunctionRegistry.java
index 1a156638..31fa315b 100644
--- a/src/main/java/net/iponweb/disthene/reader/graphite/functions/registry/FunctionRegistry.java
+++ b/src/main/java/net/iponweb/disthene/reader/graphite/functions/registry/FunctionRegistry.java
@@ -45,7 +45,9 @@ public class FunctionRegistry {
registry.put("diffSeries", DiffSeriesFunction.class);
registry.put("divideSeries", DivideSeriesFunction.class);
registry.put("drawAsInfinite", DrawAsInfiniteFunction.class);
+ registry.put("grep", GrepFunction.class);
registry.put("group", GroupFunction.class);
+ registry.put("exclude", ExcludeFunction.class);
registry.put("highestAverage", HighestAverageFunction.class);
registry.put("highestCurrent", HighestCurrentFunction.class);
registry.put("highestMax", HighestMaxFunction.class);