Merge pull request #10 from openreplay/dev

v1.0.0
This commit is contained in:
Kraiem Taha Yassine 2021-05-22 01:55:14 +02:00 committed by GitHub
commit c9a006be36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 83 additions and 74 deletions

View file

@ -1703,6 +1703,7 @@ def get_calls_errors(project_id, startTimestamp=TimeUTC.now(delta_days=-1), endT
platform=None, **args):
pg_sub_query = __get_constraints(project_id=project_id, data=args)
pg_sub_query.append("resources.type = 'fetch'")
pg_sub_query.append("resources.method IS NOT NULL")
pg_sub_query.append("resources.status/100 != 2")
with pg_client.PostgresClient() as cur:
@ -1728,6 +1729,7 @@ def get_calls_errors_4xx(project_id, startTimestamp=TimeUTC.now(delta_days=-1),
platform=None, **args):
pg_sub_query = __get_constraints(project_id=project_id, data=args)
pg_sub_query.append("resources.type = 'fetch'")
pg_sub_query.append("resources.method IS NOT NULL")
pg_sub_query.append("resources.status/100 = 4")
with pg_client.PostgresClient() as cur:
@ -1751,6 +1753,7 @@ def get_calls_errors_5xx(project_id, startTimestamp=TimeUTC.now(delta_days=-1),
platform=None, **args):
pg_sub_query = __get_constraints(project_id=project_id, data=args)
pg_sub_query.append("resources.type = 'fetch'")
pg_sub_query.append("resources.method IS NOT NULL")
pg_sub_query.append("resources.status/100 = 5")
with pg_client.PostgresClient() as cur:

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -403,7 +403,7 @@ width: 25%!important
<!-- <p style="font-size: 18px; line-height: 21px; text-align: center; margin: 0;">
<span style="font-size: 18px;">Welcome to OpenReplay!</span>
</p>-->
<h1 style="text-align: center; margin-top: 30px; line-height: 30px">Assigned session</h1>
<h1 style="text-align: center; margin-top: 30px; line-height: 30px">A recording has been assigned to you</h1>
</div>
</div>
@ -514,9 +514,9 @@ width: 25%!important
<div style="color:#555555;font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; color: #555555; font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;">
<p style="font-size: 14px; line-height: 16px; text-align: center; margin: 0;">
<a href="mailto:support@openreplay.com?subject=[User Invite] - Reporting issue"
<a href="https://github.com/openreplay/openreplay/issues"
style="text-decoration: underline; color: #009193;"
title="support@openreplay.com">Report an issue</a> | <a
>Report an issue</a> | <a
href="https://openreplay.com/" rel="noopener"
style="text-decoration: underline; color: #009193;" target="_blank">Take
a tour</a></p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -553,9 +553,9 @@ width: 25%!important
<div style="color:#555555;font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; color: #555555; font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;">
<p style="font-size: 14px; line-height: 16px; text-align: center; margin: 0;">
<a href="mailto:support@openreplay.com?subject=[User Invite] - Reporting issue"
<a href="https://github.com/openreplay/openreplay/issues"
style="text-decoration: underline; color: #009193;"
title="support@openreplay.com">Report an issue</a> | <a
>Report an issue</a> | <a
href="https://openreplay.com/" rel="noopener"
style="text-decoration: underline; color: #009193;" target="_blank">Take
a tour</a></p>

View file

@ -5,6 +5,8 @@ with open('.chalice/config.json') as json_file:
data = json.load(json_file)
stages = data.get("stages", {})
for s in stages.keys():
if environ.get("SITE_URL") is None or environ["SITE_URL"] == '':
environ["SITE_URL"] = environ.get("S3_HOST", "")
data["stages"][s]["environment_variables"] = {**stages[s].get("environment_variables", {}), **environ}
with open('.chalice/config.json', 'w') as outfile:
json.dump(data, outfile, indent=2, sort_keys=True)

View file

@ -106,24 +106,24 @@ type columnDefinition struct {
}
var LeftToDb = map[string]columnDefinition{
"performance.dom_content_loaded.average": {table: "events.pages", formula: "COALESCE(AVG(NULLIF(dom_content_loaded_time ,0)),0)"},
"performance.first_meaningful_paint.average": {table: "events.pages", formula: "COALESCE(AVG(NULLIF(first_contentful_paint_time,0)),0)"},
"performance.page_load_time.average": {table: "events.pages", formula: "AVG(NULLIF(load_time ,0))"},
"performance.dom_build_time.average": {table: "events.pages", formula: "AVG(NULLIF(dom_building_time,0))"},
"performance.speed_index.average": {table: "events.pages", formula: "AVG(NULLIF(speed_index,0))"},
"performance.page_response_time.average": {table: "events.pages", formula: "AVG(NULLIF(response_time,0))"},
"performance.ttfb.average": {table: "events.pages", formula: "AVG(NULLIF(first_paint_time,0))"},
"performance.time_to_render.averag": {table: "events.pages", formula: "AVG(NULLIF(visually_complete,0))"},
"performance.image_load_time.average": {table: "events.resources", formula: "AVG(NULLIF(duration,0))", condition: "type=='img'"},
"performance.request_load_time.average": {table: "events.resources", formula: "AVG(NULLIF(duration,0))", condition: "type=='fetch'"},
"resources.load_time.average": {table: "events.resources", formula: "AVG(NULLIF(duration,0))"},
"resources.missing.count": {table: "events.resources", formula: "COUNT(DISTINCT url_hostpath)", condition: "success==0"},
"errors.4xx_5xx.count": {table: "events.resources", formula: "COUNT(session_id)", condition: "status/100!=2"},
"errors.4xx.count": {table: "events.resources", formula: "COUNT(session_id)", condition: "status/100==4"},
"errors.5xx.count": {table: "events.resources", formula: "COUNT(session_id)", condition: "status/100==5"},
"errors.javascript.impacted_sessions.count": {table: "events.resources", formula: "COUNT(DISTINCT session_id)", condition: "success= FALSE AND type='script'"},
"performance.crashes.count": {table: "public.sessions", formula: "COUNT(DISTINCT session_id)", condition: "errors_count > 0"},
"errors.javascript.count": {table: "events.errors INNER JOIN public.errors AS m_errors USING (error_id)", formula: "COUNT(DISTINCT session_id)", condition: "source=='js_exception'"},
"performance.dom_content_loaded.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "COALESCE(AVG(NULLIF(dom_content_loaded_time ,0)),0)"},
"performance.first_meaningful_paint.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "COALESCE(AVG(NULLIF(first_contentful_paint_time,0)),0)"},
"performance.page_load_time.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(load_time ,0))"},
"performance.dom_build_time.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(dom_building_time,0))"},
"performance.speed_index.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(speed_index,0))"},
"performance.page_response_time.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(response_time,0))"},
"performance.ttfb.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(first_paint_time,0))"},
"performance.time_to_render.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(visually_complete,0))"},
"performance.image_load_time.average": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(resources.duration,0))", condition: "type='img'"},
"performance.request_load_time.average": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(resources.duration,0))", condition: "type='fetch'"},
"resources.load_time.average": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(resources.duration,0))"},
"resources.missing.count": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "COUNT(DISTINCT url_hostpath)", condition: "success= FALSE"},
"errors.4xx_5xx.count": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "COUNT(session_id)", condition: "status/100!=2"},
"errors.4xx.count": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "COUNT(session_id)", condition: "status/100=4"},
"errors.5xx.count": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "COUNT(session_id)", condition: "status/100=5"},
"errors.javascript.impacted_sessions.count": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "COUNT(DISTINCT session_id)", condition: "success= FALSE AND type='script'"},
"performance.crashes.count": {table: "(SELECT *, start_ts AS timestamp FROM public.sessions WHERE errors_count > 0) AS sessions", formula: "COUNT(DISTINCT session_id)", condition: "errors_count > 0"},
"errors.javascript.count": {table: "events.errors INNER JOIN public.errors AS m_errors USING (error_id)", formula: "COUNT(DISTINCT session_id)", condition: "source='js_exception'"},
"errors.backend.count": {table: "events.errors INNER JOIN public.errors AS m_errors USING (error_id)", formula: "COUNT(DISTINCT session_id)", condition: "source!='js_exception'"},
}
@ -161,7 +161,7 @@ func (a *Alert) Build() (sq.SelectBuilder, error) {
subQ := sq.
Select(colDef.formula + " AS value").
From(colDef.table).
Where(sq.And{sq.Eq{"project_id": a.ProjectID},
Where(sq.And{sq.Expr("project_id = $1 ", a.ProjectID),
sq.Expr(colDef.condition)})
q := sq.Select(fmt.Sprint("value, coalesce(value,0)", a.Query.Operator, a.Query.Right, " AS valid"))
if len(colDef.group) > 0 {
@ -171,44 +171,44 @@ func (a *Alert) Build() (sq.SelectBuilder, error) {
}
if a.DetectionMethod == "threshold" {
q = q.FromSelect(subQ.Where(sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60)), "stat")
q = q.FromSelect(subQ.Where(sq.Expr("timestamp>=$2 ", time.Now().Unix()-a.Options.CurrentPeriod*60)), "stat")
} else if a.DetectionMethod == "change" {
if a.Options.Change == "change" {
if len(colDef.group) == 0 {
sub1, args1, _ := subQ.Where(sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60)).ToSql()
sub1, args1, _ := subQ.Where(sq.Expr("timestamp>=$2 ", time.Now().Unix()-a.Options.CurrentPeriod*60)).ToSql()
sub2, args2, _ := subQ.Where(
sq.And{
sq.Expr("datetime<toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-2*a.Options.CurrentPeriod*60),
sq.Expr("timestamp<$3 ", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("timestamp>=$4 ", time.Now().Unix()-2*a.Options.CurrentPeriod*60),
}).ToSql()
sub1, _, _ = sq.Expr("SELECT ((" + sub1 + ")-(" + sub2 + ")) AS value").ToSql()
q = q.JoinClause("FROM ("+sub1+") AS stat", append(args1, args2...)...)
} else {
subq1 := subQ.Where(sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60))
subq1 := subQ.Where(sq.Expr("timestamp>=$2 ", time.Now().Unix()-a.Options.CurrentPeriod*60))
sub2, args2, _ := subQ.Where(
sq.And{
sq.Expr("datetime<toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-2*a.Options.CurrentPeriod*60),
sq.Expr("timestamp<$3 ", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("timestamp>=$4 ", time.Now().Unix()-2*a.Options.CurrentPeriod*60),
}).ToSql()
sub1 := sq.Select("group_value", "(stat1.value-stat2.value) AS value").FromSelect(subq1, "stat1").JoinClause("INNER JOIN ("+sub2+") AS stat2 USING(group_value)", args2...)
q = q.FromSelect(sub1, "stat")
}
} else if a.Options.Change == "percent" {
if len(colDef.group) == 0 {
sub1, args1, _ := subQ.Where(sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60)).ToSql()
sub1, args1, _ := subQ.Where(sq.Expr("timestamp>=$2 ", time.Now().Unix()-a.Options.CurrentPeriod*60)).ToSql()
sub2, args2, _ := subQ.Where(
sq.And{
sq.Expr("datetime<toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.PreviousPeriod*60-a.Options.CurrentPeriod*60),
sq.Expr("timestamp<$3 ", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("timestamp>=$4 ", time.Now().Unix()-a.Options.PreviousPeriod*60-a.Options.CurrentPeriod*60),
}).ToSql()
sub1, _, _ = sq.Expr("SELECT ((" + sub1 + ")/(" + sub2 + ")-1)*100 AS value").ToSql()
q = q.JoinClause("FROM ("+sub1+") AS stat", append(args1, args2...)...)
} else {
subq1 := subQ.Where(sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60))
subq1 := subQ.Where(sq.Expr("timestamp>=$2 ", time.Now().Unix()-a.Options.CurrentPeriod*60))
sub2, args2, _ := subQ.Where(
sq.And{
sq.Expr("datetime<toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.PreviousPeriod*60-a.Options.CurrentPeriod*60),
sq.Expr("timestamp<$3 ", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("timestamp>=$4 ", time.Now().Unix()-a.Options.PreviousPeriod*60-a.Options.CurrentPeriod*60),
}).ToSql()
sub1 := sq.Select("group_value", "(stat1.value/stat2.value-1)*100 AS value").FromSelect(subq1, "stat1").JoinClause("INNER JOIN ("+sub2+") AS stat2 USING(group_value)", args2...)
q = q.FromSelect(sub1, "stat")

View file

@ -403,7 +403,7 @@ width: 25%!important
<!-- <p style="font-size: 18px; line-height: 21px; text-align: center; margin: 0;">
<span style="font-size: 18px;">Welcome to OpenReplay!</span>
</p>-->
<h1 style="text-align: center; margin-top: 30px; line-height: 30px">Assigned session</h1>
<h1 style="text-align: center; margin-top: 30px; line-height: 30px">A recording has been assigned to you</h1>
</div>
</div>
@ -514,9 +514,9 @@ width: 25%!important
<div style="color:#555555;font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; color: #555555; font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;">
<p style="font-size: 14px; line-height: 16px; text-align: center; margin: 0;">
<a href="mailto:support@openreplay.com?subject=[User Invite] - Reporting issue"
<a href="https://github.com/openreplay/openreplay/issues"
style="text-decoration: underline; color: #009193;"
title="support@openreplay.com">Report an issue</a> | <a
>Report an issue</a> | <a
href="https://openreplay.com/" rel="noopener"
style="text-decoration: underline; color: #009193;" target="_blank">Take
a tour</a></p>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -553,9 +553,9 @@ width: 25%!important
<div style="color:#555555;font-family:-apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div style="font-size: 12px; line-height: 14px; color: #555555; font-family: -apple-system,BlinkMacSystemFont,'Helvetica Neue','Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,sans-serif;">
<p style="font-size: 14px; line-height: 16px; text-align: center; margin: 0;">
<a href="mailto:support@openreplay.com?subject=[User Invite] - Reporting issue"
<a href="https://github.com/openreplay/openreplay/issues"
style="text-decoration: underline; color: #009193;"
title="support@openreplay.com">Report an issue</a> | <a
>Report an issue</a> | <a
href="https://openreplay.com/" rel="noopener"
style="text-decoration: underline; color: #009193;" target="_blank">Take
a tour</a></p>

View file

@ -5,6 +5,8 @@ with open('.chalice/config.json') as json_file:
data = json.load(json_file)
stages = data.get("stages", {})
for s in stages.keys():
if environ.get("SITE_URL") is None or environ["SITE_URL"] == '':
environ["SITE_URL"] = environ.get("S3_HOST", "")
data["stages"][s]["environment_variables"] = {**stages[s].get("environment_variables", {}), **environ}
with open('.chalice/config.json', 'w') as outfile:
json.dump(data, outfile, indent=2, sort_keys=True)

View file

@ -106,24 +106,24 @@ type columnDefinition struct {
}
var LeftToDb = map[string]columnDefinition{
"performance.dom_content_loaded.average": {table: "events.pages", formula: "COALESCE(AVG(NULLIF(dom_content_loaded_time ,0)),0)"},
"performance.first_meaningful_paint.average": {table: "events.pages", formula: "COALESCE(AVG(NULLIF(first_contentful_paint_time,0)),0)"},
"performance.page_load_time.average": {table: "events.pages", formula: "AVG(NULLIF(load_time ,0))"},
"performance.dom_build_time.average": {table: "events.pages", formula: "AVG(NULLIF(dom_building_time,0))"},
"performance.speed_index.average": {table: "events.pages", formula: "AVG(NULLIF(speed_index,0))"},
"performance.page_response_time.average": {table: "events.pages", formula: "AVG(NULLIF(response_time,0))"},
"performance.ttfb.average": {table: "events.pages", formula: "AVG(NULLIF(first_paint_time,0))"},
"performance.time_to_render.averag": {table: "events.pages", formula: "AVG(NULLIF(visually_complete,0))"},
"performance.image_load_time.average": {table: "events.resources", formula: "AVG(NULLIF(duration,0))", condition: "type=='img'"},
"performance.request_load_time.average": {table: "events.resources", formula: "AVG(NULLIF(duration,0))", condition: "type=='fetch'"},
"resources.load_time.average": {table: "events.resources", formula: "AVG(NULLIF(duration,0))"},
"resources.missing.count": {table: "events.resources", formula: "COUNT(DISTINCT url_hostpath)", condition: "success==0"},
"errors.4xx_5xx.count": {table: "events.resources", formula: "COUNT(session_id)", condition: "status/100!=2"},
"errors.4xx.count": {table: "events.resources", formula: "COUNT(session_id)", condition: "status/100==4"},
"errors.5xx.count": {table: "events.resources", formula: "COUNT(session_id)", condition: "status/100==5"},
"errors.javascript.impacted_sessions.count": {table: "events.resources", formula: "COUNT(DISTINCT session_id)", condition: "success= FALSE AND type='script'"},
"performance.crashes.count": {table: "public.sessions", formula: "COUNT(DISTINCT session_id)", condition: "errors_count > 0"},
"errors.javascript.count": {table: "events.errors INNER JOIN public.errors AS m_errors USING (error_id)", formula: "COUNT(DISTINCT session_id)", condition: "source=='js_exception'"},
"performance.dom_content_loaded.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "COALESCE(AVG(NULLIF(dom_content_loaded_time ,0)),0)"},
"performance.first_meaningful_paint.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "COALESCE(AVG(NULLIF(first_contentful_paint_time,0)),0)"},
"performance.page_load_time.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(load_time ,0))"},
"performance.dom_build_time.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(dom_building_time,0))"},
"performance.speed_index.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(speed_index,0))"},
"performance.page_response_time.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(response_time,0))"},
"performance.ttfb.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(first_paint_time,0))"},
"performance.time_to_render.average": {table: "events.pages INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(visually_complete,0))"},
"performance.image_load_time.average": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(resources.duration,0))", condition: "type='img'"},
"performance.request_load_time.average": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(resources.duration,0))", condition: "type='fetch'"},
"resources.load_time.average": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "AVG(NULLIF(resources.duration,0))"},
"resources.missing.count": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "COUNT(DISTINCT url_hostpath)", condition: "success= FALSE"},
"errors.4xx_5xx.count": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "COUNT(session_id)", condition: "status/100!=2"},
"errors.4xx.count": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "COUNT(session_id)", condition: "status/100=4"},
"errors.5xx.count": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "COUNT(session_id)", condition: "status/100=5"},
"errors.javascript.impacted_sessions.count": {table: "events.resources INNER JOIN public.sessions USING(session_id)", formula: "COUNT(DISTINCT session_id)", condition: "success= FALSE AND type='script'"},
"performance.crashes.count": {table: "(SELECT *, start_ts AS timestamp FROM public.sessions WHERE errors_count > 0) AS sessions", formula: "COUNT(DISTINCT session_id)", condition: "errors_count > 0"},
"errors.javascript.count": {table: "events.errors INNER JOIN public.errors AS m_errors USING (error_id)", formula: "COUNT(DISTINCT session_id)", condition: "source='js_exception'"},
"errors.backend.count": {table: "events.errors INNER JOIN public.errors AS m_errors USING (error_id)", formula: "COUNT(DISTINCT session_id)", condition: "source!='js_exception'"},
}
@ -161,7 +161,7 @@ func (a *Alert) Build() (sq.SelectBuilder, error) {
subQ := sq.
Select(colDef.formula + " AS value").
From(colDef.table).
Where(sq.And{sq.Eq{"project_id": a.ProjectID},
Where(sq.And{sq.Expr("project_id = $1 ", a.ProjectID),
sq.Expr(colDef.condition)})
q := sq.Select(fmt.Sprint("value, coalesce(value,0)", a.Query.Operator, a.Query.Right, " AS valid"))
if len(colDef.group) > 0 {
@ -171,44 +171,44 @@ func (a *Alert) Build() (sq.SelectBuilder, error) {
}
if a.DetectionMethod == "threshold" {
q = q.FromSelect(subQ.Where(sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60)), "stat")
q = q.FromSelect(subQ.Where(sq.Expr("timestamp>=$2 ", time.Now().Unix()-a.Options.CurrentPeriod*60)), "stat")
} else if a.DetectionMethod == "change" {
if a.Options.Change == "change" {
if len(colDef.group) == 0 {
sub1, args1, _ := subQ.Where(sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60)).ToSql()
sub1, args1, _ := subQ.Where(sq.Expr("timestamp>=$2 ", time.Now().Unix()-a.Options.CurrentPeriod*60)).ToSql()
sub2, args2, _ := subQ.Where(
sq.And{
sq.Expr("datetime<toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-2*a.Options.CurrentPeriod*60),
sq.Expr("timestamp<$3 ", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("timestamp>=$4 ", time.Now().Unix()-2*a.Options.CurrentPeriod*60),
}).ToSql()
sub1, _, _ = sq.Expr("SELECT ((" + sub1 + ")-(" + sub2 + ")) AS value").ToSql()
q = q.JoinClause("FROM ("+sub1+") AS stat", append(args1, args2...)...)
} else {
subq1 := subQ.Where(sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60))
subq1 := subQ.Where(sq.Expr("timestamp>=$2 ", time.Now().Unix()-a.Options.CurrentPeriod*60))
sub2, args2, _ := subQ.Where(
sq.And{
sq.Expr("datetime<toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-2*a.Options.CurrentPeriod*60),
sq.Expr("timestamp<$3 ", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("timestamp>=$4 ", time.Now().Unix()-2*a.Options.CurrentPeriod*60),
}).ToSql()
sub1 := sq.Select("group_value", "(stat1.value-stat2.value) AS value").FromSelect(subq1, "stat1").JoinClause("INNER JOIN ("+sub2+") AS stat2 USING(group_value)", args2...)
q = q.FromSelect(sub1, "stat")
}
} else if a.Options.Change == "percent" {
if len(colDef.group) == 0 {
sub1, args1, _ := subQ.Where(sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60)).ToSql()
sub1, args1, _ := subQ.Where(sq.Expr("timestamp>=$2 ", time.Now().Unix()-a.Options.CurrentPeriod*60)).ToSql()
sub2, args2, _ := subQ.Where(
sq.And{
sq.Expr("datetime<toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.PreviousPeriod*60-a.Options.CurrentPeriod*60),
sq.Expr("timestamp<$3 ", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("timestamp>=$4 ", time.Now().Unix()-a.Options.PreviousPeriod*60-a.Options.CurrentPeriod*60),
}).ToSql()
sub1, _, _ = sq.Expr("SELECT ((" + sub1 + ")/(" + sub2 + ")-1)*100 AS value").ToSql()
q = q.JoinClause("FROM ("+sub1+") AS stat", append(args1, args2...)...)
} else {
subq1 := subQ.Where(sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60))
subq1 := subQ.Where(sq.Expr("timestamp>=$2 ", time.Now().Unix()-a.Options.CurrentPeriod*60))
sub2, args2, _ := subQ.Where(
sq.And{
sq.Expr("datetime<toDateTime(?)", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("datetime>=toDateTime(?)", time.Now().Unix()-a.Options.PreviousPeriod*60-a.Options.CurrentPeriod*60),
sq.Expr("timestamp<$3 ", time.Now().Unix()-a.Options.CurrentPeriod*60),
sq.Expr("timestamp>=$4 ", time.Now().Unix()-a.Options.PreviousPeriod*60-a.Options.CurrentPeriod*60),
}).ToSql()
sub1 := sq.Select("group_value", "(stat1.value/stat2.value-1)*100 AS value").FromSelect(subq1, "stat1").JoinClause("INNER JOIN ("+sub2+") AS stat2 USING(group_value)", args2...)
q = q.FromSelect(sub1, "stat")

View file

@ -47,8 +47,10 @@ function PreferencesMenu({ activeTab, appearance, history }) {
/>
</div>
{
<div className="mb-4">
<SideMenuitem
active={ activeTab === CLIENT_TABS.WEBHOOKS }
title="Webhooks"