This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 14e208354d [Feature](Nereids) support nereids event for logging the
cascades states and transformation. (#13659)
14e208354d is described below
commit 14e208354de12395b31d142e9f325f3ad5c8dd94
Author: mch_ucchi <[email protected]>
AuthorDate: Thu Dec 1 21:42:40 2022 +0800
[Feature](Nereids) support nereids event for logging the cascades states
and transformation. (#13659)
Add an event producer, channel, consumer system to support the feature as
title and you can turn it on using set
enable_nereids_event = true;
For more information, please see
fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/README.md
---
.../org/apache/doris/nereids/NereidsPlanner.java | 9 +-
.../java/org/apache/doris/nereids/jobs/Job.java | 77 ++++++------
.../doris/nereids/jobs/cascades/ApplyRuleJob.java | 19 ++-
.../nereids/jobs/cascades/CostAndEnforcerJob.java | 1 +
.../nereids/jobs/cascades/DeriveStatsJob.java | 10 ++
.../jobs/cascades/OptimizeGroupExpressionJob.java | 1 +
.../nereids/jobs/cascades/OptimizeGroupJob.java | 4 +
.../nereids/jobs/rewrite/RewriteBottomUpJob.java | 13 ++
.../nereids/jobs/rewrite/RewriteTopDownJob.java | 15 ++-
.../nereids/jobs/rewrite/VisitorRewriteJob.java | 5 +
.../apache/doris/nereids/memo/GroupExpression.java | 8 ++
.../java/org/apache/doris/nereids/memo/Memo.java | 28 ++++-
.../apache/doris/nereids/metrics/CounterType.java | 29 +++++
.../org/apache/doris/nereids/metrics/Event.java | 56 +++++++++
.../apache/doris/nereids/metrics/EventChannel.java | 128 +++++++++++++++++++
.../doris/nereids/metrics/EventConsumer.java | 56 +++++++++
.../doris/nereids/metrics/EventEnhancer.java | 54 +++++++++
.../apache/doris/nereids/metrics/EventFilter.java | 37 ++++++
.../doris/nereids/metrics/EventProducer.java | 71 +++++++++++
.../doris/nereids/metrics/EventSwitchParser.java | 91 ++++++++++++++
.../org/apache/doris/nereids/metrics/README.md | 60 +++++++++
.../doris/nereids/metrics/TracerSupplier.java | 25 ++++
.../nereids/metrics/consumer/FileDumpConsumer.java | 60 +++++++++
.../nereids/metrics/consumer/LogConsumer.java | 40 ++++++
.../nereids/metrics/consumer/PrintConsumer.java | 40 ++++++
.../metrics/enhancer/AddCounterEventEnhancer.java | 36 ++++++
.../metrics/event/CostStateUpdateEvent.java | 48 ++++++++
.../doris/nereids/metrics/event/CounterEvent.java | 77 ++++++++++++
.../doris/nereids/metrics/event/EnforcerEvent.java | 56 +++++++++
.../nereids/metrics/event/FunctionCallEvent.java | 41 +++++++
.../nereids/metrics/event/GroupMergeEvent.java | 53 ++++++++
.../doris/nereids/metrics/event/StateEvent.java | 36 ++++++
.../nereids/metrics/event/StatsStateEvent.java | 44 +++++++
.../nereids/metrics/event/TransformEvent.java | 59 +++++++++
.../properties/EnforceMissingPropertiesHelper.java | 10 +-
.../doris/nereids/trees/plans/AbstractPlan.java | 13 +-
.../java/org/apache/doris/qe/SessionVariable.java | 41 +++++++
.../main/java/org/apache/doris/qe/VariableMgr.java | 13 ++
.../apache/doris/nereids/metrics/EventTest.java | 135 +++++++++++++++++++++
39 files changed, 1539 insertions(+), 60 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java
index 35a41b9e1f..aa381445dd 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/NereidsPlanner.java
@@ -30,6 +30,7 @@ import org.apache.doris.nereids.jobs.batch.OptimizeRulesJob;
import org.apache.doris.nereids.jobs.cascades.DeriveStatsJob;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.metrics.event.CounterEvent;
import org.apache.doris.nereids.processor.post.PlanPostProcessors;
import org.apache.doris.nereids.processor.pre.PlanPreprocessors;
import org.apache.doris.nereids.properties.PhysicalProperties;
@@ -58,7 +59,6 @@ import java.util.stream.Collectors;
*/
public class NereidsPlanner extends Planner {
public static final Logger LOG =
LogManager.getLogger(NereidsPlanner.class);
-
private CascadesContext cascadesContext;
private final StatementContext statementContext;
private List<ScanNode> scanNodeList = null;
@@ -90,12 +90,7 @@ public class NereidsPlanner extends Planner {
PhysicalPlanTranslator physicalPlanTranslator = new
PhysicalPlanTranslator();
PlanTranslatorContext planTranslatorContext = new
PlanTranslatorContext(cascadesContext);
if (ConnectContext.get().getSessionVariable().isEnableNereidsTrace()) {
- String tree = physicalPlan.treeString();
- System.out.println(tree);
- LOG.info(tree);
- String memo = cascadesContext.getMemo().toString();
- System.out.println(memo);
- LOG.info(memo);
+ CounterEvent.clearCounter();
}
PlanFragment root = physicalPlanTranslator.translatePlan(physicalPlan,
planTranslatorContext);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/Job.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/Job.java
index c6e1a4edd3..a0e45e1796 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/Job.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/Job.java
@@ -21,10 +21,18 @@ import
org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.memo.CopyInResult;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.memo.Memo;
+import org.apache.doris.nereids.metrics.CounterType;
+import org.apache.doris.nereids.metrics.EventChannel;
+import org.apache.doris.nereids.metrics.EventProducer;
+import org.apache.doris.nereids.metrics.TracerSupplier;
+import org.apache.doris.nereids.metrics.consumer.LogConsumer;
+import org.apache.doris.nereids.metrics.enhancer.AddCounterEventEnhancer;
+import org.apache.doris.nereids.metrics.event.CounterEvent;
+import org.apache.doris.nereids.metrics.event.TransformEvent;
import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleSet;
import org.apache.doris.nereids.trees.plans.Plan;
-import org.apache.doris.qe.ConnectContext;
import com.google.common.base.Preconditions;
import org.apache.logging.log4j.LogManager;
@@ -38,13 +46,17 @@ import java.util.stream.Collectors;
/**
* Abstract class for all job using for analyze and optimize query plan in
Nereids.
*/
-public abstract class Job {
+public abstract class Job implements TracerSupplier {
+ // counter tracer to count expression transform times.
+ protected static final EventProducer COUNTER_TRACER = new
EventProducer(CounterEvent.class,
+ EventChannel.getDefaultChannel()
+ .addEnhancers(new AddCounterEventEnhancer())
+ .addConsumers(new LogConsumer(CounterEvent.class,
EventChannel.LOG)));
public final Logger logger = LogManager.getLogger(getClass());
protected JobType type;
protected JobContext context;
protected boolean once;
- protected final boolean enableTrace;
public Job(JobType type, JobContext context) {
this(type, context, true);
@@ -55,10 +67,6 @@ public abstract class Job {
this.type = type;
this.context = context;
this.once = once;
- ConnectContext connectContext = ConnectContext.get();
- this.enableTrace = connectContext == null
- ? false
- : connectContext.getSessionVariable().isEnableNereidsTrace();
}
public void pushJob(Job job) {
@@ -88,48 +96,41 @@ public abstract class Job {
public abstract void execute() throws AnalysisException;
+ public EventProducer getEventTracer() {
+ throw new UnsupportedOperationException("get_event_tracer is
unsupported");
+ }
+
protected Optional<CopyInResult> invokeRewriteRuleWithTrace(Rule rule,
Plan before, Group targetGroup) {
context.onInvokeRule(rule.getRuleType());
-
- String traceBefore = enableTrace ? getPlanTraceLog() : null;
+ COUNTER_TRACER.log(CounterEvent.of(Memo.getStateId(),
+ CounterType.EXPRESSION_TRANSFORM, targetGroup,
targetGroup.getLogicalExpression(), before));
List<Plan> afters = rule.transform(before,
context.getCascadesContext());
Preconditions.checkArgument(afters.size() == 1);
Plan after = afters.get(0);
-
- if (after != before) {
- CopyInResult result = context.getCascadesContext()
- .getMemo()
- .copyIn(after, targetGroup, rule.isRewrite());
-
- if ((result.generateNewExpression ||
result.correspondingExpression.getOwnerGroup() != targetGroup)
- && enableTrace) {
- String traceAfter = getPlanTraceLog();
- printTraceLog(rule, traceBefore, traceAfter);
- }
-
- return Optional.of(result);
+ if (after == before) {
+ return Optional.empty();
}
- return Optional.empty();
- }
-
- protected String getPlanTraceLog() {
- return context.getCascadesContext()
+ CopyInResult result = context.getCascadesContext()
.getMemo()
- .copyOut(false)
- .treeString();
- }
+ .copyIn(after, targetGroup, rule.isRewrite());
- protected String getMemoTraceLog() {
- return context.getCascadesContext()
- .getMemo()
- .getRoot()
- .treeString();
+ if (result.generateNewExpression ||
result.correspondingExpression.getOwnerGroup() != targetGroup) {
+
getEventTracer().log(TransformEvent.of(targetGroup.getLogicalExpression(),
before, afters,
+ rule.getRuleType()), rule::isRewrite);
+ }
+
+ return Optional.of(result);
}
- protected void printTraceLog(Rule rule, String traceBefore, String
traceAfter) {
- logger.info("========== {} {} ==========\nbefore:\n{}\n\nafter:\n{}\n",
- getClass().getSimpleName(), rule.getRuleType(), traceBefore,
traceAfter);
+ /**
+ * count the job execution times of groupExpressions, all groupExpressions
will be inclusive.
+ * TODO: count a specific groupExpression.
+ * @param groupExpression the groupExpression at current job.
+ */
+ protected void countJobExecutionTimesOfGroupExpressions(GroupExpression
groupExpression) {
+ COUNTER_TRACER.log(CounterEvent.of(Memo.getStateId(),
CounterType.JOB_EXECUTION,
+ groupExpression.getOwnerGroup(), groupExpression,
groupExpression.getPlan()));
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java
index 40cdfe1a64..31117c0507 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/ApplyRuleJob.java
@@ -23,6 +23,10 @@ import org.apache.doris.nereids.jobs.JobContext;
import org.apache.doris.nereids.jobs.JobType;
import org.apache.doris.nereids.memo.CopyInResult;
import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.metrics.EventChannel;
+import org.apache.doris.nereids.metrics.EventProducer;
+import org.apache.doris.nereids.metrics.consumer.LogConsumer;
+import org.apache.doris.nereids.metrics.event.TransformEvent;
import org.apache.doris.nereids.pattern.GroupExpressionMatching;
import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.trees.plans.Plan;
@@ -34,6 +38,8 @@ import java.util.List;
* Job to apply rule on {@link GroupExpression}.
*/
public class ApplyRuleJob extends Job {
+ private static final EventProducer APPLY_RULE_TRACER = new
EventProducer(TransformEvent.class,
+ EventChannel.getDefaultChannel().addConsumers(new
LogConsumer(TransformEvent.class, EventChannel.LOG)));
private final GroupExpression groupExpression;
private final Rule rule;
@@ -55,14 +61,11 @@ public class ApplyRuleJob extends Job {
if (groupExpression.hasApplied(rule)) {
return;
}
+ countJobExecutionTimesOfGroupExpressions(groupExpression);
GroupExpressionMatching groupExpressionMatching
= new GroupExpressionMatching(rule.getPattern(),
groupExpression);
for (Plan plan : groupExpressionMatching) {
- String traceBefore = enableTrace ? getMemoTraceLog() : null;
- context.onInvokeRule(rule.getRuleType());
-
- boolean changed = false;
List<Plan> newPlans = rule.transform(plan,
context.getCascadesContext());
for (Plan newPlan : newPlans) {
CopyInResult result = context.getCascadesContext()
@@ -71,8 +74,6 @@ public class ApplyRuleJob extends Job {
if (!result.generateNewExpression) {
continue;
}
-
- changed = true;
GroupExpression newGroupExpression =
result.correspondingExpression;
if (newPlan instanceof LogicalPlan) {
pushJob(new OptimizeGroupExpressionJob(newGroupExpression,
context));
@@ -80,10 +81,8 @@ public class ApplyRuleJob extends Job {
} else {
pushJob(new CostAndEnforcerJob(newGroupExpression,
context));
}
- }
- if (changed && enableTrace) {
- String traceAfter = getMemoTraceLog();
- printTraceLog(rule, traceBefore, traceAfter);
+ APPLY_RULE_TRACER.log(TransformEvent.of(groupExpression, plan,
newPlans, rule.getRuleType()),
+ rule::isRewrite);
}
}
groupExpression.setApplied(rule);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/CostAndEnforcerJob.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/CostAndEnforcerJob.java
index f684e9430d..f11f693cf7 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/CostAndEnforcerJob.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/CostAndEnforcerJob.java
@@ -101,6 +101,7 @@ public class CostAndEnforcerJob extends Job implements
Cloneable {
*/
@Override
public void execute() {
+ countJobExecutionTimesOfGroupExpressions(groupExpression);
// Do init logic of root plan/groupExpr of `subplan`, only run once
per task.
if (curChildIndex == -1) {
curNodeCost = 0;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/DeriveStatsJob.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/DeriveStatsJob.java
index 8797327311..f274f5e6eb 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/DeriveStatsJob.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/DeriveStatsJob.java
@@ -22,12 +22,19 @@ import org.apache.doris.nereids.jobs.JobContext;
import org.apache.doris.nereids.jobs.JobType;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.metrics.EventChannel;
+import org.apache.doris.nereids.metrics.EventProducer;
+import org.apache.doris.nereids.metrics.consumer.LogConsumer;
+import org.apache.doris.nereids.metrics.event.StatsStateEvent;
import org.apache.doris.nereids.stats.StatsCalculator;
/**
* Job to derive stats for {@link GroupExpression} in {@link
org.apache.doris.nereids.memo.Memo}.
*/
public class DeriveStatsJob extends Job {
+ private static final EventProducer STATS_STATE_TRACER = new EventProducer(
+ StatsStateEvent.class,
+ EventChannel.getDefaultChannel().addConsumers(new
LogConsumer(StatsStateEvent.class, EventChannel.LOG)));
private final GroupExpression groupExpression;
private boolean deriveChildren;
@@ -56,6 +63,7 @@ public class DeriveStatsJob extends Job {
@Override
public void execute() {
+ countJobExecutionTimesOfGroupExpressions(groupExpression);
if (!deriveChildren) {
deriveChildren = true;
pushJob(new DeriveStatsJob(this));
@@ -66,6 +74,8 @@ public class DeriveStatsJob extends Job {
}
} else {
StatsCalculator.estimate(groupExpression);
+ STATS_STATE_TRACER.log(StatsStateEvent.of(groupExpression,
+ groupExpression.getOwnerGroup().getStatistics()));
}
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/OptimizeGroupExpressionJob.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/OptimizeGroupExpressionJob.java
index c530bb2b4f..18e53463ea 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/OptimizeGroupExpressionJob.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/OptimizeGroupExpressionJob.java
@@ -40,6 +40,7 @@ public class OptimizeGroupExpressionJob extends Job {
@Override
public void execute() {
+ countJobExecutionTimesOfGroupExpressions(groupExpression);
List<Rule> validRules = new ArrayList<>();
List<Rule> implementationRules = getRuleSet().getImplementationRules();
List<Rule> explorationRules = getRuleSet().getExplorationRules();
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/OptimizeGroupJob.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/OptimizeGroupJob.java
index 8395adfebe..2bda4ce569 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/OptimizeGroupJob.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/cascades/OptimizeGroupJob.java
@@ -22,6 +22,9 @@ import org.apache.doris.nereids.jobs.JobContext;
import org.apache.doris.nereids.jobs.JobType;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.memo.Memo;
+import org.apache.doris.nereids.metrics.CounterType;
+import org.apache.doris.nereids.metrics.event.CounterEvent;
import java.util.List;
@@ -38,6 +41,7 @@ public class OptimizeGroupJob extends Job {
@Override
public void execute() {
+ COUNTER_TRACER.log(CounterEvent.of(Memo.getStateId(),
CounterType.JOB_EXECUTION, group, null, null));
if (group.getCostLowerBound() > context.getCostUpperBound()
||
group.getLowestCostPlan(context.getRequiredProperties()).isPresent()) {
return;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteBottomUpJob.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteBottomUpJob.java
index f9f74e5b81..22a1fb7f26 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteBottomUpJob.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteBottomUpJob.java
@@ -24,6 +24,10 @@ import org.apache.doris.nereids.jobs.JobType;
import org.apache.doris.nereids.memo.CopyInResult;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.metrics.EventChannel;
+import org.apache.doris.nereids.metrics.EventProducer;
+import org.apache.doris.nereids.metrics.consumer.LogConsumer;
+import org.apache.doris.nereids.metrics.event.TransformEvent;
import org.apache.doris.nereids.pattern.GroupExpressionMatching;
import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleFactory;
@@ -38,6 +42,9 @@ import java.util.stream.Collectors;
* Bottom up job for rewrite, use pattern match.
*/
public class RewriteBottomUpJob extends Job {
+ private static final EventProducer RULE_TRANSFORM_TRACER = new
EventProducer(
+ TransformEvent.class,
+ EventChannel.getDefaultChannel().addConsumers(new
LogConsumer(TransformEvent.class, EventChannel.LOG)));
private final Group group;
private final List<Rule> rules;
private final boolean childrenOptimized;
@@ -60,6 +67,11 @@ public class RewriteBottomUpJob extends Job {
this.childrenOptimized = childrenOptimized;
}
+ @Override
+ public EventProducer getEventTracer() {
+ return RULE_TRANSFORM_TRACER;
+ }
+
@Override
public void execute() throws AnalysisException {
GroupExpression logicalExpression = group.getLogicalExpression();
@@ -72,6 +84,7 @@ public class RewriteBottomUpJob extends Job {
return;
}
+ countJobExecutionTimesOfGroupExpressions(logicalExpression);
List<Rule> validRules = getValidRules(logicalExpression, rules);
for (Rule rule : validRules) {
GroupExpressionMatching groupExpressionMatching
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteTopDownJob.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteTopDownJob.java
index fe9fdcf747..6baa6b1e5a 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteTopDownJob.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/RewriteTopDownJob.java
@@ -17,12 +17,17 @@
package org.apache.doris.nereids.jobs.rewrite;
+import org.apache.doris.nereids.NereidsPlanner;
import org.apache.doris.nereids.jobs.Job;
import org.apache.doris.nereids.jobs.JobContext;
import org.apache.doris.nereids.jobs.JobType;
import org.apache.doris.nereids.memo.CopyInResult;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.metrics.EventChannel;
+import org.apache.doris.nereids.metrics.EventProducer;
+import org.apache.doris.nereids.metrics.consumer.LogConsumer;
+import org.apache.doris.nereids.metrics.event.TransformEvent;
import org.apache.doris.nereids.pattern.GroupExpressionMatching;
import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleFactory;
@@ -39,6 +44,9 @@ import java.util.stream.Collectors;
* Top down job for rewrite, use pattern match.
*/
public class RewriteTopDownJob extends Job {
+ private static final EventProducer RULE_TRANSFORM_TRACER = new
EventProducer(
+ TransformEvent.class,
+ EventChannel.getDefaultChannel().addConsumers(new
LogConsumer(TransformEvent.class, NereidsPlanner.LOG)));
private final Group group;
private final List<Rule> rules;
@@ -65,10 +73,15 @@ public class RewriteTopDownJob extends Job {
this.rules = Objects.requireNonNull(rules, "rules cannot be null");
}
+ @Override
+ public EventProducer getEventTracer() {
+ return RULE_TRANSFORM_TRACER;
+ }
+
@Override
public void execute() {
GroupExpression logicalExpression = group.getLogicalExpression();
-
+ countJobExecutionTimesOfGroupExpressions(logicalExpression);
List<Rule> validRules = getValidRules(logicalExpression, rules);
for (Rule rule : validRules) {
Preconditions.checkArgument(rule.isRewrite(),
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/VisitorRewriteJob.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/VisitorRewriteJob.java
index f579de23ad..9510a4147c 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/VisitorRewriteJob.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/rewrite/VisitorRewriteJob.java
@@ -23,6 +23,9 @@ import org.apache.doris.nereids.jobs.JobContext;
import org.apache.doris.nereids.jobs.JobType;
import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.memo.Memo;
+import org.apache.doris.nereids.metrics.CounterType;
+import org.apache.doris.nereids.metrics.event.CounterEvent;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.visitor.DefaultPlanRewriter;
@@ -49,6 +52,8 @@ public class VisitorRewriteJob extends Job {
public void execute() {
GroupExpression logicalExpression = group.getLogicalExpression();
Plan root =
context.getCascadesContext().getMemo().copyOut(logicalExpression, true);
+ COUNTER_TRACER.log(CounterEvent.of(Memo.getStateId(),
CounterType.JOB_EXECUTION, group, logicalExpression,
+ root));
Plan rewrittenRoot = root.accept(planRewriter, context);
context.getCascadesContext().getMemo().copyIn(rewrittenRoot, group,
true);
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/GroupExpression.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/GroupExpression.java
index 9fedd98523..d7c3631ed8 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/GroupExpression.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/GroupExpression.java
@@ -20,6 +20,10 @@ package org.apache.doris.nereids.memo;
import org.apache.doris.common.Pair;
import org.apache.doris.nereids.analyzer.UnboundRelation;
import org.apache.doris.nereids.cost.CostEstimate;
+import org.apache.doris.nereids.metrics.EventChannel;
+import org.apache.doris.nereids.metrics.EventProducer;
+import org.apache.doris.nereids.metrics.consumer.LogConsumer;
+import org.apache.doris.nereids.metrics.event.CostStateUpdateEvent;
import org.apache.doris.nereids.properties.PhysicalProperties;
import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleType;
@@ -41,6 +45,9 @@ import java.util.Optional;
* Representation for group expression in cascades optimizer.
*/
public class GroupExpression {
+ private static final EventProducer COST_STATE_TRACER = new
EventProducer(CostStateUpdateEvent.class,
+ EventChannel.getDefaultChannel().addConsumers(new
LogConsumer(CostStateUpdateEvent.class,
+ EventChannel.LOG)));
private double cost = 0.0;
private CostEstimate costEstimate = null;
private Group ownerGroup;
@@ -172,6 +179,7 @@ public class GroupExpression {
*/
public boolean updateLowestCostTable(PhysicalProperties outputProperties,
List<PhysicalProperties> childrenInputProperties, double cost) {
+ COST_STATE_TRACER.log(CostStateUpdateEvent.of(this, cost,
outputProperties));
if (lowestCostTable.containsKey(outputProperties)) {
if (lowestCostTable.get(outputProperties).first > cost) {
lowestCostTable.put(outputProperties, Pair.of(cost,
childrenInputProperties));
diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java
index 2fa73db681..1c24ed1772 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/memo/Memo.java
@@ -20,6 +20,10 @@ package org.apache.doris.nereids.memo;
import org.apache.doris.common.IdGenerator;
import org.apache.doris.nereids.CascadesContext;
import org.apache.doris.nereids.StatementContext;
+import org.apache.doris.nereids.metrics.EventChannel;
+import org.apache.doris.nereids.metrics.EventProducer;
+import org.apache.doris.nereids.metrics.consumer.LogConsumer;
+import org.apache.doris.nereids.metrics.event.GroupMergeEvent;
import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.rules.analysis.CTEContext;
import org.apache.doris.nereids.trees.expressions.Expression;
@@ -28,6 +32,7 @@ import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
+import org.apache.doris.qe.ConnectContext;
import org.apache.doris.statistics.StatsDeriveResult;
import com.google.common.base.Preconditions;
@@ -48,6 +53,9 @@ import javax.annotation.Nullable;
*/
public class Memo {
// generate group id in memo is better for test, since we can reproduce
exactly same Memo.
+ private static final EventProducer GROUP_MERGE_TRACER = new
EventProducer(GroupMergeEvent.class,
+ EventChannel.getDefaultChannel().addConsumers(new
LogConsumer(GroupMergeEvent.class, EventChannel.LOG)));
+ private static long stateId = 0;
private final IdGenerator<GroupId> groupIdGenerator =
GroupId.createGenerator();
private final Map<GroupId, Group> groups = Maps.newLinkedHashMap();
// we could not use Set, because Set does not have get method.
@@ -75,6 +83,10 @@ public class Memo {
return groupExpressions;
}
+ public static long getStateId() {
+ return stateId;
+ }
+
/**
* Add plan to Memo.
*
@@ -86,10 +98,21 @@ public class Memo {
* is the corresponding group expression of the plan
*/
public CopyInResult copyIn(Plan plan, @Nullable Group target, boolean
rewrite) {
+ CopyInResult result;
if (rewrite) {
- return doRewrite(plan, target);
+ result = doRewrite(plan, target);
} else {
- return doCopyIn(plan, target);
+ result = doCopyIn(plan, target);
+ }
+ maybeAddStateId(result);
+ return result;
+ }
+
+ private void maybeAddStateId(CopyInResult result) {
+ if (ConnectContext.get() != null
+ &&
ConnectContext.get().getSessionVariable().isEnableNereidsTrace()
+ && result.generateNewExpression) {
+ stateId++;
}
}
@@ -407,6 +430,7 @@ public class Memo {
needReplaceChild.add(groupExpression);
}
}
+ GROUP_MERGE_TRACER.log(GroupMergeEvent.of(source, destination,
needReplaceChild));
for (GroupExpression groupExpression : needReplaceChild) {
// After change GroupExpression children, the hashcode will change,
// so need to reinsert into map.
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/CounterType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/CounterType.java
new file mode 100644
index 0000000000..c5ded21a27
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/CounterType.java
@@ -0,0 +1,29 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics;
+
+/**
+ * counter type
+ */
+public enum CounterType {
+ PLAN_CONSTRUCTOR,
+ EXPRESSION_TRANSFORM,
+ JOB_EXECUTION,
+ EXPRESSION_CONSTRUCTOR,
+ FUNCTION_CALL,
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/Event.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/Event.java
new file mode 100644
index 0000000000..1a31076658
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/Event.java
@@ -0,0 +1,56 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics;
+
+import org.apache.doris.nereids.util.Utils;
+import org.apache.doris.qe.ConnectContext;
+
+/**
+ * event
+ */
+public abstract class Event implements Cloneable {
+ private final long stateId;
+
+ protected Event() {
+ this.stateId = -1;
+ }
+
+ protected Event(long stateId) {
+ this.stateId = stateId;
+ }
+
+ protected static boolean checkConnectContext(Class<? extends Event>
targetClass) {
+ return ConnectContext.get() != null
+ &&
ConnectContext.get().getSessionVariable().isEnableNereidsTrace()
+ &&
ConnectContext.get().getSessionVariable().getParsedNereidsEventMode().contains(targetClass);
+ }
+
+ public final String toJson() {
+ return Utils.toSqlString("Event", "StateId", stateId);
+ }
+
+ @Override
+ public String toString() {
+ return toJson();
+ }
+
+ @Override
+ public Event clone() throws CloneNotSupportedException {
+ return (Event) super.clone();
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventChannel.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventChannel.java
new file mode 100644
index 0000000000..83e844a0b1
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventChannel.java
@@ -0,0 +1,128 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * event channel
+ */
+public class EventChannel {
+ public static final Logger LOG = LogManager.getLogger(EventChannel.class);
+ private static final EventChannel DEFAULT_CHANNEL = new
EventChannel().start();
+ private final Map<Class<? extends Event>, List<EventConsumer>> consumers =
Maps.newHashMap();
+ private final Map<Class<? extends Event>, EventEnhancer> enhancers =
Maps.newHashMap();
+ private final BlockingQueue<Event> queue = new LinkedBlockingQueue<>(4096);
+ private final AtomicBoolean isStop = new AtomicBoolean(false);
+ private Thread thread = null;
+
+ public void add(Event e) {
+ try {
+ queue.put(e);
+ } catch (Exception exception) {
+ LOG.warn("Exception when put event: ", exception);
+ }
+ }
+
+ public synchronized EventChannel addConsumers(EventConsumer ...consumers) {
+ for (EventConsumer consumer : consumers) {
+ this.consumers.computeIfAbsent(consumer.getTargetClass(), k ->
Lists.newArrayList()).add(consumer);
+ }
+ return this;
+ }
+
+ public synchronized EventChannel addEnhancers(EventEnhancer ...enhancers) {
+ for (EventEnhancer enhancer : enhancers) {
+ this.enhancers.putIfAbsent(enhancer.getTargetClass(), enhancer);
+ }
+ return this;
+ }
+
+ public static EventChannel getDefaultChannel() {
+ return DEFAULT_CHANNEL;
+ }
+
+ private class Worker implements Runnable {
+ @Override
+ public void run() {
+ while (!isStop.get() || !queue.isEmpty()) {
+ try {
+ Event e = queue.poll();
+ if (e == null) {
+ continue;
+ }
+ for (EventConsumer consumer : consumers.get(e.getClass()))
{
+ if (enhancers.containsKey(e.getClass())) {
+ enhancers.get(e.getClass()).enhance(e);
+ }
+ consumer.consume(e);
+ }
+ } catch (Exception exception) {
+ LOG.warn("encounter exception when push event: ",
exception);
+ }
+ }
+ for (List<EventConsumer> consumerList : consumers.values()) {
+ for (EventConsumer consumer : consumerList) {
+ consumer.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * worker thread start.
+ */
+ public EventChannel start() {
+ isStop.set(false);
+ if (thread == null) {
+ thread = new Thread(new Worker(), "nereids_event");
+ thread.setDaemon(true);
+ try {
+ thread.start();
+ } catch (IllegalThreadStateException e) {
+ LOG.warn("start worker failed: ", e);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * stop channel
+ */
+ public void stop() {
+ isStop.set(true);
+ if (thread != null) {
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ LOG.warn("join worker failed.", e);
+ } finally {
+ thread = null;
+ }
+ }
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventConsumer.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventConsumer.java
new file mode 100644
index 0000000000..9979c322c7
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventConsumer.java
@@ -0,0 +1,56 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics;
+
+import java.util.Objects;
+
+/**
+ * consumer
+ */
+public abstract class EventConsumer {
+ private final Class<? extends Event> targetClass;
+
+ protected EventConsumer(Class<? extends Event> targetClass) {
+ this.targetClass = targetClass;
+ }
+
+ public abstract void consume(Event event);
+
+ public Class<? extends Event> getTargetClass() {
+ return targetClass;
+ }
+
+ public void close() {}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ EventConsumer consumer = (EventConsumer) o;
+ return Objects.equals(targetClass, consumer.targetClass);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(targetClass);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventEnhancer.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventEnhancer.java
new file mode 100644
index 0000000000..86c89d0fca
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventEnhancer.java
@@ -0,0 +1,54 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics;
+
+import java.util.Objects;
+
+/**
+ * event enhancer
+ */
+public abstract class EventEnhancer {
+ private final Class<? extends Event> targetClass;
+
+ public EventEnhancer(Class<? extends Event> targetClass) {
+ this.targetClass = targetClass;
+ }
+
+ public Class<? extends Event> getTargetClass() {
+ return targetClass;
+ }
+
+ public abstract void enhance(Event e);
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ EventEnhancer enhancer = (EventEnhancer) o;
+ return Objects.equals(targetClass, enhancer.targetClass);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(targetClass);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventFilter.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventFilter.java
new file mode 100644
index 0000000000..1bc9fe6554
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventFilter.java
@@ -0,0 +1,37 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics;
+
+/**
+ * event filter
+ */
+public abstract class EventFilter {
+ private final Class<? extends Event> targetClass;
+
+ public EventFilter(Class<? extends Event> targetClass) {
+ this.targetClass = targetClass;
+ }
+
+ public Event checkEvent(Event event) {
+ return event;
+ }
+
+ public Class<? extends Event> getTargetClass() {
+ return targetClass;
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventProducer.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventProducer.java
new file mode 100644
index 0000000000..67b9bcfaef
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventProducer.java
@@ -0,0 +1,71 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics;
+
+import com.google.common.base.Preconditions;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Supplier;
+
+/**
+ * event producer
+ */
+public class EventProducer {
+ private final EventChannel channel;
+ private final List<EventFilter> filters;
+ private final Class<? extends Event> eventClass;
+
+ /**
+ * constructor
+ * @param eventClass event's class info for the producer, a producer can
only supply one type of event.
+ * @param filters event's filter, the event that satisfy the filter's
condition can be submitted to the channel.
+ * the filters are AND in logic, see checkAndLog for detail.
+ * @param channel the channel to transport event to consumer.
+ */
+ public EventProducer(Class<? extends Event> eventClass, EventChannel
channel, EventFilter ...filters) {
+ this.channel = channel;
+ Preconditions.checkArgument(Arrays.stream(filters).allMatch(f ->
f.getTargetClass().equals(eventClass)));
+ this.filters = Arrays.asList(filters);
+ this.eventClass = eventClass;
+ }
+
+ private void checkAndLog(Event event) {
+ for (EventFilter filter : filters) {
+ event = filter.checkEvent(event);
+ if (event == null) {
+ return;
+ }
+ }
+ channel.add(event);
+ }
+
+ public void log(Event event) {
+ if (event == null || channel == null) {
+ return;
+ }
+ Preconditions.checkArgument(event.getClass().equals(eventClass));
+ checkAndLog(event);
+ }
+
+ public void log(Event event, Supplier<Boolean> f) {
+ if (f.get()) {
+ log(event);
+ }
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventSwitchParser.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventSwitchParser.java
new file mode 100644
index 0000000000..2bd5287b0e
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/EventSwitchParser.java
@@ -0,0 +1,91 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics;
+
+import org.apache.doris.nereids.metrics.event.CostStateUpdateEvent;
+import org.apache.doris.nereids.metrics.event.CounterEvent;
+import org.apache.doris.nereids.metrics.event.EnforcerEvent;
+import org.apache.doris.nereids.metrics.event.FunctionCallEvent;
+import org.apache.doris.nereids.metrics.event.GroupMergeEvent;
+import org.apache.doris.nereids.metrics.event.StatsStateEvent;
+import org.apache.doris.nereids.metrics.event.TransformEvent;
+
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * parser
+ */
+public class EventSwitchParser {
+ private static final Map<String, Class<? extends Event>> EVENT_TYPE_SET =
+ new Builder<String, Class<? extends Event>>()
+ .put("costState", CostStateUpdateEvent.class)
+ .put("counter", CounterEvent.class)
+ .put("enforcer", EnforcerEvent.class)
+ .put("functionCall", FunctionCallEvent.class)
+ .put("groupMerge", GroupMergeEvent.class)
+ .put("statsState", StatsStateEvent.class)
+ .put("transform", TransformEvent.class)
+ .build();
+
+ /**
+ * parse
+ */
+ public static Set<Class<? extends Event>> parse(List<String>
eventTypeMode) {
+ if ("all".equals(eventTypeMode.get(0))) {
+ if (eventTypeMode.size() == 1) {
+ return ImmutableSet.copyOf(EVENT_TYPE_SET.values());
+ }
+ Map targetClasses = Maps.newHashMap(EVENT_TYPE_SET);
+ for (String str : eventTypeMode.subList(2, eventTypeMode.size())) {
+ targetClasses.remove(str);
+ }
+ return ImmutableSet.copyOf(targetClasses.values());
+ }
+ return eventTypeMode.stream()
+ .filter(EVENT_TYPE_SET::containsKey)
+ .map(str -> ((Class<? extends Event>) EVENT_TYPE_SET.get(str)))
+ .collect(ImmutableSet.toImmutableSet());
+ }
+
+ /**
+ * check
+ */
+ public static List<String> checkEventModeStringAndSplit(String
eventTypeMode) {
+ List<String> strings =
Arrays.stream(eventTypeMode.toLowerCase().split("[\\s+,]"))
+ .map(String::trim)
+ .collect(Collectors.toList());
+ if (strings.size() == 0) {
+ return null;
+ } else if ("all".equals(strings.get(0))) {
+ if (strings.size() == 1) {
+ return strings;
+ } else if (strings.size() == 2 ||
!"except".equals(strings.get(1))) {
+ return null;
+ }
+ }
+ return strings;
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/README.md
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/README.md
new file mode 100644
index 0000000000..8660e6cc09
--- /dev/null
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/README.md
@@ -0,0 +1,60 @@
+# Docs of Event System
+
+## Introduction
+
+Event System is designed for log the event when cascades running like: rule
transformation and cost calculation for specific physical properties, see event
module detailed.
+
+## Usage
+
+Data Streaming Graph:
+
+```
+EventProducer::log() --> create an event and try to log it to channel
+ │
+ ▼
+EventFilter::checkEvent() --> check an event with the condition in filter,
return nullif failed.
+ │
+ ▼
+EventChannel::add() --> add the event to channel
+ │
+ ▼
+EventChannel::Worker::run() --> a while loop to consume the event
+ │
+ ▼
+EventEnhancer::enhance() --> do something before consume the event
+ │
+ ▼
+EventConsumer::consume() --> consume the event.
+```
+
+- Use it in your program
+
+1. Set NereidsEventMode, see format below.
+2. Create a public static EventChannel and add enhancers and consumers, lastly
set connectContext.
+3. Create a static EventProducer at the class where you want to submit event.
+4. Set the class info of an event to the EventProducer.
+5. Register the channel and filter to the EventProducer.
+6. Call EventProducer::log to submit event.
+
+- Create a new type of Consumer
+
+Write a new class override the Consumer and implement consume method.
+
+- Create a new type of Event
+
+Write a new class override the Event is ok.
+
+- Create a new type of Enhancer
+
+Write a new class override the Enhancer and implement enhance method.
+
+- Create a new type of Filter
+
+Write a new class override the Filter and implement filter method.
+
+See the classes have written as example for detail.
+
+NereidsEventMode format
+all -> use all event
+all except event_1, event_2, ..., event_n -> use all events excluding the
event_1~n
+event_1, event_2, ..., event_n -> use event_1~n
\ No newline at end of file
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/TracerSupplier.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/TracerSupplier.java
new file mode 100644
index 0000000000..b423b6528e
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/TracerSupplier.java
@@ -0,0 +1,25 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics;
+
+/**
+ * tracer supplier
+ */
+public interface TracerSupplier {
+ EventProducer getEventTracer();
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/consumer/FileDumpConsumer.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/consumer/FileDumpConsumer.java
new file mode 100644
index 0000000000..ea71d041b4
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/consumer/FileDumpConsumer.java
@@ -0,0 +1,60 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.consumer;
+
+import org.apache.doris.nereids.metrics.Event;
+import org.apache.doris.nereids.metrics.EventConsumer;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * file dump consumer
+ */
+public class FileDumpConsumer extends EventConsumer {
+ private static final Logger LOG =
LogManager.getLogger(FileDumpConsumer.class);
+ private final FileOutputStream fs;
+
+ public FileDumpConsumer(Class<? extends Event> eventClass, String
fileName) throws FileNotFoundException {
+ super(eventClass);
+ this.fs = new FileOutputStream(fileName);
+ }
+
+ @Override
+ public void consume(Event event) {
+ try {
+ fs.write(event.toString().getBytes(StandardCharsets.UTF_8));
+ } catch (IOException e) {
+ LOG.warn("write to file encounter exception: ", e);
+ }
+ }
+
+ @Override
+ public void close() {
+ try {
+ fs.close();
+ } catch (IOException e) {
+ LOG.warn("close file output stream encounter: ", e);
+ }
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/consumer/LogConsumer.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/consumer/LogConsumer.java
new file mode 100644
index 0000000000..679b8ff442
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/consumer/LogConsumer.java
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.consumer;
+
+import org.apache.doris.nereids.metrics.Event;
+import org.apache.doris.nereids.metrics.EventConsumer;
+
+import org.apache.logging.log4j.Logger;
+
+/**
+ * log consumer
+ */
+public class LogConsumer extends EventConsumer {
+ private final Logger logger;
+
+ public LogConsumer(Class<? extends Event> targetClass, Logger logger) {
+ super(targetClass);
+ this.logger = logger;
+ }
+
+ @Override
+ public void consume(Event e) {
+ logger.info(e.toString());
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/consumer/PrintConsumer.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/consumer/PrintConsumer.java
new file mode 100644
index 0000000000..16e65fc747
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/consumer/PrintConsumer.java
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.consumer;
+
+import org.apache.doris.nereids.metrics.Event;
+import org.apache.doris.nereids.metrics.EventConsumer;
+
+import java.io.PrintStream;
+
+/**
+ * print consumer
+ */
+public class PrintConsumer extends EventConsumer {
+ private final PrintStream printStream;
+
+ public PrintConsumer(Class<? extends Event> targetClass, PrintStream
printStream) {
+ super(targetClass);
+ this.printStream = printStream;
+ }
+
+ @Override
+ public void consume(Event event) {
+ printStream.println(event.toString());
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/enhancer/AddCounterEventEnhancer.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/enhancer/AddCounterEventEnhancer.java
new file mode 100644
index 0000000000..90d442d510
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/enhancer/AddCounterEventEnhancer.java
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.enhancer;
+
+import org.apache.doris.nereids.metrics.Event;
+import org.apache.doris.nereids.metrics.EventEnhancer;
+import org.apache.doris.nereids.metrics.event.CounterEvent;
+
+/**
+ * add counter event enhancer
+ */
+public class AddCounterEventEnhancer extends EventEnhancer {
+ public AddCounterEventEnhancer() {
+ super(CounterEvent.class);
+ }
+
+ @Override
+ public void enhance(Event e) {
+ CounterEvent.updateCounter(((CounterEvent) e).getCounterType());
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/CostStateUpdateEvent.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/CostStateUpdateEvent.java
new file mode 100644
index 0000000000..312fc60d2a
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/CostStateUpdateEvent.java
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.event;
+
+import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.properties.PhysicalProperties;
+import org.apache.doris.nereids.util.Utils;
+
+/**
+ * cost state event
+ */
+public class CostStateUpdateEvent extends StateEvent {
+ private final double cost;
+ private final PhysicalProperties physicalProperties;
+
+ private CostStateUpdateEvent(GroupExpression groupExpression, double cost,
PhysicalProperties physicalProperties) {
+ super(groupExpression);
+ this.cost = cost;
+ this.physicalProperties = physicalProperties;
+ }
+
+ public static CostStateUpdateEvent of(GroupExpression groupExpression,
double cost,
+ PhysicalProperties physicalProperties) {
+ return checkConnectContext(CostStateUpdateEvent.class)
+ ? new CostStateUpdateEvent(groupExpression, cost,
physicalProperties) : null;
+ }
+
+ @Override
+ public String toString() {
+ return Utils.toSqlString("CostStateEvent", "groupExpression",
getGroupExpression(),
+ "cost", cost, "physicalProperties", physicalProperties);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/CounterEvent.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/CounterEvent.java
new file mode 100644
index 0000000000..024dd53941
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/CounterEvent.java
@@ -0,0 +1,77 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.event;
+
+import org.apache.doris.nereids.memo.Group;
+import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.metrics.CounterType;
+import org.apache.doris.nereids.metrics.Event;
+import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.util.Utils;
+
+import com.google.common.collect.Maps;
+
+import java.util.Map;
+
+/**
+ * counter event
+ */
+public class CounterEvent extends Event {
+ private static final Map<CounterType, Long> COUNTER_MAP =
Maps.newHashMap();
+ private final CounterType counterType;
+ private final Group group;
+ private final GroupExpression groupExpression;
+ private final Plan plan;
+
+ /**
+ * counter event
+ */
+ private CounterEvent(long stateId, CounterType counterType, Group group,
+ GroupExpression groupExpression, Plan plan) {
+ super(stateId);
+ this.counterType = counterType;
+ this.group = group;
+ this.groupExpression = groupExpression;
+ this.plan = plan;
+ }
+
+ public static CounterEvent of(long stateId, CounterType counterType, Group
group,
+ GroupExpression groupExpression, Plan plan) {
+ return checkConnectContext(CounterEvent.class)
+ ? new CounterEvent(stateId, counterType, group,
groupExpression, plan) : null;
+ }
+
+ @Override
+ public String toString() {
+ return Utils.toSqlString("CounterEvent", "count",
COUNTER_MAP.get(counterType),
+ "count", counterType, "group", group,
+ "groupExpression", groupExpression, "plan", plan);
+ }
+
+ public static void updateCounter(CounterType counterType) {
+ COUNTER_MAP.compute(counterType, (t, l) -> l == null ? 1L : l + 1);
+ }
+
+ public static void clearCounter() {
+ COUNTER_MAP.clear();
+ }
+
+ public CounterType getCounterType() {
+ return counterType;
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/EnforcerEvent.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/EnforcerEvent.java
new file mode 100644
index 0000000000..50f085295e
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/EnforcerEvent.java
@@ -0,0 +1,56 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.event;
+
+import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.metrics.Event;
+import org.apache.doris.nereids.properties.PhysicalProperties;
+import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
+import org.apache.doris.nereids.util.Utils;
+
+/**
+ * enforcer event
+ */
+public class EnforcerEvent extends Event {
+ private final GroupExpression groupExpression;
+ private final PhysicalPlan enforce;
+ private final PhysicalProperties before;
+ private final PhysicalProperties after;
+
+ private EnforcerEvent(GroupExpression groupExpression, PhysicalPlan
enforce, PhysicalProperties before,
+ PhysicalProperties after) {
+ this.groupExpression = groupExpression;
+ this.enforce = enforce;
+ this.before = before;
+ this.after = after;
+ }
+
+ public static EnforcerEvent of(GroupExpression groupExpression,
PhysicalPlan enforce, PhysicalProperties before,
+ PhysicalProperties after) {
+ return checkConnectContext(EnforcerEvent.class)
+ ? new EnforcerEvent(groupExpression, enforce, before, after) :
null;
+ }
+
+ @Override
+ public String toString() {
+ return Utils.toSqlString("EnforcerEvent", "groupExpression",
groupExpression,
+ "enforce", enforce,
+ "before", before,
+ "after", after);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/FunctionCallEvent.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/FunctionCallEvent.java
new file mode 100644
index 0000000000..775f0990da
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/FunctionCallEvent.java
@@ -0,0 +1,41 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.event;
+
+import org.apache.doris.nereids.metrics.Event;
+import org.apache.doris.nereids.util.Utils;
+
+/**
+ * function call event
+ */
+public class FunctionCallEvent extends Event {
+ private final String callFuncNameAndLine;
+
+ private FunctionCallEvent(String callFuncNameAndLine) {
+ this.callFuncNameAndLine = callFuncNameAndLine;
+ }
+
+ public static FunctionCallEvent of(String callFuncNameAndLine) {
+ return checkConnectContext(FunctionCallEvent.class) ? new
FunctionCallEvent(callFuncNameAndLine) : null;
+ }
+
+ @Override
+ public String toString() {
+ return Utils.toSqlString("FunctionCallEvent", "callFuncNameAndLine='",
callFuncNameAndLine);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/GroupMergeEvent.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/GroupMergeEvent.java
new file mode 100644
index 0000000000..b0ec57be03
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/GroupMergeEvent.java
@@ -0,0 +1,53 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.event;
+
+import org.apache.doris.nereids.memo.Group;
+import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.metrics.Event;
+import org.apache.doris.nereids.util.Utils;
+
+import java.util.List;
+
+/**
+ * group merge event
+ */
+public class GroupMergeEvent extends Event {
+ private final Group source;
+ private final Group destination;
+ private final List<GroupExpression> needReplaceGroupExpressions;
+
+ private GroupMergeEvent(Group source, Group destination,
List<GroupExpression> needReplaceGroupExpressions) {
+ this.source = source;
+ this.destination = destination;
+ this.needReplaceGroupExpressions = needReplaceGroupExpressions;
+ }
+
+ public static GroupMergeEvent of(Group source, Group destination,
+ List<GroupExpression> needReplaceGroupExpressions) {
+ return checkConnectContext(GroupMergeEvent.class)
+ ? new GroupMergeEvent(source, destination,
needReplaceGroupExpressions) : null;
+ }
+
+ @Override
+ public String toString() {
+ return Utils.toSqlString("GroupMergeEvent", "source", source,
+ "destination", destination,
+ "needReplaceGroupExpressions", needReplaceGroupExpressions);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/StateEvent.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/StateEvent.java
new file mode 100644
index 0000000000..21f415768c
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/StateEvent.java
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.event;
+
+import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.metrics.Event;
+
+/**
+ * state event
+ */
+public abstract class StateEvent extends Event {
+ private final GroupExpression groupExpression;
+
+ protected StateEvent(GroupExpression groupExpression) {
+ this.groupExpression = groupExpression;
+ }
+
+ protected GroupExpression getGroupExpression() {
+ return groupExpression;
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/StatsStateEvent.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/StatsStateEvent.java
new file mode 100644
index 0000000000..2dd420ef4f
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/StatsStateEvent.java
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.event;
+
+import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.util.Utils;
+import org.apache.doris.statistics.StatsDeriveResult;
+
+/**
+ * stats state event
+ */
+public class StatsStateEvent extends StateEvent {
+ private final StatsDeriveResult statsDeriveResult;
+
+ private StatsStateEvent(GroupExpression groupExpression, StatsDeriveResult
statsDeriveResult) {
+ super(groupExpression);
+ this.statsDeriveResult = statsDeriveResult;
+ }
+
+ public static StatsStateEvent of(GroupExpression groupExpression,
StatsDeriveResult statsDeriveResult) {
+ return checkConnectContext(StatsStateEvent.class)
+ ? new StatsStateEvent(groupExpression, statsDeriveResult) :
null;
+ }
+
+ @Override
+ public String toString() {
+ return Utils.toSqlString("StatsStateEvent", "statsDeriveResult",
statsDeriveResult);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/TransformEvent.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/TransformEvent.java
new file mode 100644
index 0000000000..4ebd593dc5
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/metrics/event/TransformEvent.java
@@ -0,0 +1,59 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics.event;
+
+import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.metrics.Event;
+import org.apache.doris.nereids.rules.RuleType;
+import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.util.Utils;
+
+import java.util.List;
+
+/**
+ * transform event
+ */
+public class TransformEvent extends Event {
+ private final GroupExpression groupExpression;
+ private final Plan before;
+ private final List<Plan> afters;
+ private final RuleType ruleType;
+
+ private TransformEvent(GroupExpression groupExpression, Plan before,
List<Plan> afters, RuleType ruleType) {
+ this.groupExpression = groupExpression;
+ this.before = before;
+ this.afters = afters;
+ this.ruleType = ruleType;
+ }
+
+ public static TransformEvent of(GroupExpression groupExpression, Plan
before, List<Plan> afters,
+ RuleType ruleType) {
+ return checkConnectContext(TransformEvent.class)
+ ? new TransformEvent(groupExpression, before, afters,
ruleType) : null;
+ }
+
+ public GroupExpression getGroupExpression() {
+ return groupExpression;
+ }
+
+ @Override
+ public String toString() {
+ return Utils.toSqlString("TransformEvent", "groupExpression",
groupExpression,
+ "before", before, "afters", afters, "ruleType", ruleType);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/EnforceMissingPropertiesHelper.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/EnforceMissingPropertiesHelper.java
index 2ce69854c0..b8e0fecc38 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/EnforceMissingPropertiesHelper.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/properties/EnforceMissingPropertiesHelper.java
@@ -20,7 +20,12 @@ package org.apache.doris.nereids.properties;
import org.apache.doris.nereids.cost.CostCalculator;
import org.apache.doris.nereids.jobs.JobContext;
import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.metrics.EventChannel;
+import org.apache.doris.nereids.metrics.EventProducer;
+import org.apache.doris.nereids.metrics.consumer.LogConsumer;
+import org.apache.doris.nereids.metrics.event.EnforcerEvent;
import org.apache.doris.nereids.properties.DistributionSpecHash.ShuffleType;
+import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
import com.google.common.collect.Lists;
@@ -29,7 +34,8 @@ import com.google.common.collect.Lists;
* Enforce add missing properties for child.
*/
public class EnforceMissingPropertiesHelper {
-
+ private static final EventProducer ENFORCER_TRACER = new
EventProducer(EnforcerEvent.class,
+ EventChannel.getDefaultChannel().addConsumers(new
LogConsumer(EnforcerEvent.class, EventChannel.LOG)));
private final JobContext context;
private final GroupExpression groupExpression;
private double curTotalCost;
@@ -138,6 +144,8 @@ public class EnforceMissingPropertiesHelper {
PhysicalProperties oldOutputProperty,
PhysicalProperties newOutputProperty) {
context.getCascadesContext().getMemo().addEnforcerPlan(enforcer,
groupExpression.getOwnerGroup());
+ ENFORCER_TRACER.log(EnforcerEvent.of(groupExpression, ((PhysicalPlan)
enforcer.getPlan()),
+ oldOutputProperty, newOutputProperty));
curTotalCost += CostCalculator.calculateCost(enforcer);
if (enforcer.updateLowestCostTable(newOutputProperty,
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/AbstractPlan.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/AbstractPlan.java
index b266a554de..253678e48d 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/AbstractPlan.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/AbstractPlan.java
@@ -19,6 +19,13 @@ package org.apache.doris.nereids.trees.plans;
import org.apache.doris.nereids.analyzer.Unbound;
import org.apache.doris.nereids.memo.GroupExpression;
+import org.apache.doris.nereids.memo.Memo;
+import org.apache.doris.nereids.metrics.CounterType;
+import org.apache.doris.nereids.metrics.EventChannel;
+import org.apache.doris.nereids.metrics.EventProducer;
+import org.apache.doris.nereids.metrics.consumer.LogConsumer;
+import org.apache.doris.nereids.metrics.enhancer.AddCounterEventEnhancer;
+import org.apache.doris.nereids.metrics.event.CounterEvent;
import org.apache.doris.nereids.properties.LogicalProperties;
import org.apache.doris.nereids.trees.AbstractTreeNode;
import org.apache.doris.nereids.trees.expressions.ExprId;
@@ -39,7 +46,10 @@ import javax.annotation.Nullable;
* Abstract class for all concrete plan node.
*/
public abstract class AbstractPlan extends AbstractTreeNode<Plan> implements
Plan {
-
+ private static final EventProducer PLAN_CONSTRUCT_TRACER = new
EventProducer(CounterEvent.class,
+ EventChannel.getDefaultChannel()
+ .addEnhancers(new AddCounterEventEnhancer())
+ .addConsumers(new LogConsumer(CounterEvent.class,
EventChannel.LOG)));
protected final StatsDeriveResult statsDeriveResult;
protected final PlanType type;
protected final Optional<GroupExpression> groupExpression;
@@ -66,6 +76,7 @@ public abstract class AbstractPlan extends
AbstractTreeNode<Plan> implements Pla
this.logicalPropertiesSupplier = Suppliers.memoize(() ->
optLogicalProperties.orElseGet(
this::computeLogicalProperties));
this.statsDeriveResult = statsDeriveResult;
+ PLAN_CONSTRUCT_TRACER.log(CounterEvent.of(Memo.getStateId(),
CounterType.PLAN_CONSTRUCTOR, null, null, null));
}
@Override
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
index ded896d24b..a46e2a2999 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java
@@ -21,11 +21,14 @@ import org.apache.doris.common.Config;
import org.apache.doris.common.io.Text;
import org.apache.doris.common.io.Writable;
import org.apache.doris.common.util.TimeUtils;
+import org.apache.doris.nereids.metrics.Event;
+import org.apache.doris.nereids.metrics.EventSwitchParser;
import org.apache.doris.qe.VariableMgr.VarAttr;
import org.apache.doris.thrift.TQueryOptions;
import org.apache.doris.thrift.TResourceLimit;
import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.simple.JSONObject;
@@ -37,8 +40,10 @@ import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Random;
+import java.util.Set;
/**
* System variable.
@@ -232,6 +237,8 @@ public class SessionVariable implements Serializable,
Writable {
public static final String ENABLE_ELIMINATE_SORT_NODE =
"enable_eliminate_sort_node";
+ public static final String NEREIDS_TRACE_EVENT_MODE =
"nereids_trace_event_mode";
+
public static final String INTERNAL_SESSION = "internal_session";
public static final String PARTITIONED_HASH_JOIN_ROWS_THRESHOLD =
"partitioned_hash_join_rows_threshold";
@@ -643,6 +650,40 @@ public class SessionVariable implements Serializable,
Writable {
this.enableShareHashTableForBroadcastJoin = random.nextBoolean();
}
+ /**
+ * syntax:
+ * all -> use all event
+ * all except event_1, event_2, ..., event_n -> use all events excluding
the event_1~n
+ * event_1, event_2, ..., event_n -> use event_1~n
+ */
+ @VariableMgr.VarAttr(name = NEREIDS_TRACE_EVENT_MODE, checker =
"checkNereidsTraceEventMode")
+ public String nereidsTraceEventMode = "all";
+
+ private Set<Class<? extends Event>> parsedNereidsEventMode =
EventSwitchParser.parse(Lists.newArrayList("all"));
+
+ public void setEnableNereidsTrace(boolean enableNereidsTrace) {
+ this.enableNereidsTrace = enableNereidsTrace;
+ }
+
+ public void setNereidsTraceEventMode(String nereidsTraceEventMode) {
+ checkNereidsTraceEventMode(nereidsTraceEventMode);
+ this.nereidsTraceEventMode = nereidsTraceEventMode;
+ }
+
+ public void checkNereidsTraceEventMode(String nereidsTraceEventMode) {
+ List<String> strings =
EventSwitchParser.checkEventModeStringAndSplit(nereidsTraceEventMode);
+ if (strings != null) {
+ parsedNereidsEventMode = EventSwitchParser.parse(strings);
+ }
+ if (parsedNereidsEventMode == null) {
+ throw new UnsupportedOperationException("nereids_trace_event_mode
syntax error, please check");
+ }
+ }
+
+ public Set<Class<? extends Event>> getParsedNereidsEventMode() {
+ return parsedNereidsEventMode;
+ }
+
public String getBlockEncryptionMode() {
return blockEncryptionMode;
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
b/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
index d6c224e68c..214f983c8b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
@@ -29,6 +29,7 @@ import org.apache.doris.common.ErrorReport;
import org.apache.doris.common.PatternMatcher;
import org.apache.doris.persist.GlobalVarPersistInfo;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Lists;
@@ -140,6 +141,14 @@ public class VariableMgr {
if (VariableVarConverters.hasConverter(attr.name())) {
value = VariableVarConverters.encode(attr.name(),
value).toString();
}
+ if (!attr.checker().equals("")) {
+ Preconditions.checkArgument(obj instanceof SessionVariable);
+ try {
+
SessionVariable.class.getDeclaredMethod(attr.checker()).invoke(obj);
+ } catch (Exception e) {
+ ErrorReport.reportDdlException(ErrorCode.ERR_INVALID_VALUE,
attr.name(), value, e.getMessage());
+ }
+ }
try {
switch (field.getType().getSimpleName()) {
case "boolean":
@@ -516,6 +525,10 @@ public class VariableMgr {
String maxValue() default "0";
+ // the function name that check the VarAttr before setting it to
sessionVariable
+ // only support check function: 0 argument and 0 return value, if an
error occurs, throw an exception.
+ String checker() default "";
+
// Set to true if the variables need to be forwarded along with
forward statement.
boolean needForward() default false;
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/metrics/EventTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/metrics/EventTest.java
new file mode 100644
index 0000000000..94efff68d0
--- /dev/null
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/metrics/EventTest.java
@@ -0,0 +1,135 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.metrics;
+
+import org.apache.doris.nereids.metrics.consumer.PrintConsumer;
+import org.apache.doris.nereids.metrics.event.CounterEvent;
+import org.apache.doris.nereids.metrics.event.EnforcerEvent;
+import org.apache.doris.nereids.metrics.event.GroupMergeEvent;
+import org.apache.doris.nereids.metrics.event.TransformEvent;
+import org.apache.doris.nereids.rules.RuleType;
+import org.apache.doris.utframe.TestWithFeService;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+public class EventTest extends TestWithFeService {
+ private EventChannel channel;
+ private List<EventProducer> producers;
+
+ private final StringBuilder builder = new StringBuilder();
+ private final PrintStream printStream = new PrintStream(new OutputStream()
{
+ @Override
+ public void write(int b) {
+ builder.append((char) b);
+ }
+ });
+
+ @Override
+ public void runBeforeAll() {
+ connectContext.getSessionVariable().setEnableNereidsTrace(true);
+ connectContext.getSessionVariable().setEnableNereidsPlanner(true);
+ channel = new EventChannel()
+ .addConsumers(
+ new PrintConsumer(CounterEvent.class, printStream),
+ new PrintConsumer(TransformEvent.class, printStream),
+ new PrintConsumer(EnforcerEvent.class, printStream),
+ new PrintConsumer(GroupMergeEvent.class, printStream))
+ .addEnhancers(
+ new EventEnhancer(CounterEvent.class) {
+ @Override
+ public void enhance(Event e) {
+ CounterEvent.updateCounter(((CounterEvent)
e).getCounterType());
+ }
+ }
+ );
+ producers = ImmutableList.of(
+ new EventProducer(CounterEvent.class, channel,
+ new EventFilter(CounterEvent.class) { },
+ new EventFilter(CounterEvent.class) { }),
+ new EventProducer(TransformEvent.class, channel,
+ new EventFilter(TransformEvent.class) {
+ @Override
+ public Event checkEvent(Event event) {
+ return ((TransformEvent)
event).getGroupExpression() == null ? event : null;
+ }
+ })
+ );
+ channel.start();
+ }
+
+ @Override
+ public void runAfterAll() {
+ channel.stop();
+ Assertions.assertEquals(
+ "CounterEvent ( count=1, count=PLAN_CONSTRUCTOR, group=null,
groupExpression=null, plan=null )\n"
+ + "CounterEvent ( count=2, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "CounterEvent ( count=3, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "CounterEvent ( count=4, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "CounterEvent ( count=5, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "CounterEvent ( count=6, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "TransformEvent ( groupExpression=null, before=null,
afters=[], ruleType=AGGREGATE_DISASSEMBLE )\n"
+ + "CounterEvent ( count=7, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "TransformEvent ( groupExpression=null, before=null,
afters=[], ruleType=AGGREGATE_DISASSEMBLE )\n"
+ + "CounterEvent ( count=8, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "TransformEvent ( groupExpression=null, before=null,
afters=[], ruleType=AGGREGATE_DISASSEMBLE )\n"
+ + "CounterEvent ( count=9, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "TransformEvent ( groupExpression=null, before=null,
afters=[], ruleType=AGGREGATE_DISASSEMBLE )\n"
+ + "CounterEvent ( count=10, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "TransformEvent ( groupExpression=null, before=null,
afters=[], ruleType=AGGREGATE_DISASSEMBLE )\n"
+ + "CounterEvent ( count=11, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "TransformEvent ( groupExpression=null, before=null,
afters=[], ruleType=AGGREGATE_DISASSEMBLE )\n"
+ + "CounterEvent ( count=12, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "TransformEvent ( groupExpression=null, before=null,
afters=[], ruleType=AGGREGATE_DISASSEMBLE )\n"
+ + "CounterEvent ( count=13, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "TransformEvent ( groupExpression=null, before=null,
afters=[], ruleType=AGGREGATE_DISASSEMBLE )\n"
+ + "CounterEvent ( count=14, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "TransformEvent ( groupExpression=null, before=null,
afters=[], ruleType=AGGREGATE_DISASSEMBLE )\n"
+ + "CounterEvent ( count=15, count=PLAN_CONSTRUCTOR,
group=null, groupExpression=null, plan=null )\n"
+ + "TransformEvent ( groupExpression=null, before=null,
afters=[], ruleType=AGGREGATE_DISASSEMBLE )\n",
+ builder.toString());
+ CounterEvent.clearCounter();
+ }
+
+ @Test
+ public void testEvent() {
+ connectContext.getSessionVariable().setNereidsTraceEventMode("all
except transform");
+ for (int i = 0; i < 10; ++i) {
+ producers.get(i % 2).log(i % 2 == 0
+ ? CounterEvent.of(0, CounterType.PLAN_CONSTRUCTOR, null,
null, null)
+ : TransformEvent.of(null, null, ImmutableList.of(),
RuleType.AGGREGATE_DISASSEMBLE));
+ }
+ connectContext.getSessionVariable().setNereidsTraceEventMode("all");
+ for (int i = 0; i < 10; ++i) {
+ producers.get(i % 2).log(i % 2 == 0
+ ? CounterEvent.of(0, CounterType.PLAN_CONSTRUCTOR, null,
null, null)
+ : TransformEvent.of(null, null, ImmutableList.of(),
RuleType.AGGREGATE_DISASSEMBLE));
+ }
+ connectContext.getSessionVariable().setNereidsTraceEventMode("counter,
transform");
+ for (int i = 0; i < 10; ++i) {
+ producers.get(i % 2).log(i % 2 == 0
+ ? CounterEvent.of(0, CounterType.PLAN_CONSTRUCTOR, null,
null, null)
+ : TransformEvent.of(null, null, ImmutableList.of(),
RuleType.AGGREGATE_DISASSEMBLE));
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]