Compare commits

...

236 Commits

Author SHA1 Message Date
Srikanth Chekuri
ec21d1bca1 fix: tests 2024-01-04 07:53:11 +05:30
Srikanth Chekuri
52e98bcddf chore: add ee query limits 2024-01-04 00:55:58 +05:30
Srikanth Chekuri
a8b7e9582a Merge branch 'develop' of github.com:SigNoz/signoz into query-limits 2024-01-02 20:53:51 +05:30
Yunus M
bdd7778e58 update readme.md (#3814)
* chore: update read.me - fe maintainers

* chore: update code owner for frontend codebase
2024-01-02 17:42:36 +05:30
Srikanth Chekuri
105216de3e chore: add prepare query for delta/unspecified timeseries (#4167)
* chore: update BuilderQuery struct and add PrepareTimeseriesFilterQuery

* chore: add prepare query for cumulative/unspecified timeseries

* chore: add prepare query for delta/unspecified timeseries

* chore: update group by to work with 23.11+

* chore: fix test

---------

Co-authored-by: Nityananda Gohain <nityanandagohain@gmail.com>
2023-12-30 22:53:09 +05:30
Ankit Nayan
3072b7eb01 merging main 2023-12-29 22:29:15 +05:30
Raj Kamal Singh
fd9a502012 fix: opamp server: do not panic if config generation fails (#4307) 2023-12-29 21:55:38 +05:30
Prashant Shahi
cf6dc827cc Merge pull request #4306 from SigNoz/release/v0.36.2
Release/v0.36.2
2023-12-29 19:21:12 +05:30
Prashant Shahi
6530873994 Merge branch 'main' into release/v0.36.2 2023-12-29 19:12:41 +05:30
Prashant Shahi
c9c0bd38be chore(signoz): 📌 pin versions: SigNoz 0.36.2
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-12-29 19:24:12 +05:45
Prashant Shahi
9ac22fcb10 Merge branch 'develop' into release/v0.36.1 2023-12-29 19:06:53 +05:45
Raj Kamal Singh
86ff865842 Fix: logs pipelines: ignore coalesce op when generating nil check for add value expressions (#4305)
* chore: panic if agent config recommendation can't be generated

* chore: add case with coalesce op in field nil check generation tests

* fix: ignore expr ast member nodes that contain coalesce op in them
2023-12-29 18:21:01 +05:30
Rajat Dabade
e792c48f6d [Refactor]: css fixes (#4248) 2023-12-29 16:05:46 +05:30
Rajat Dabade
8ee92516ca [Refactor]: updated css for height of Panel in LeftContainer (#4030)
* refactor: updated css

* refactor: updated the css

* refactor: removed overflow hidden
2023-12-29 15:52:35 +05:30
Prashant Shahi
79c05d8fa8 Merge pull request #4304 from SigNoz/release/v0.36.1
Release/v0.36.1
2023-12-29 15:39:38 +05:30
Prashant Shahi
019bc8c1df chore(signoz): 📌 pin versions: SigNoz 0.36.1, SigNoz OtelCollector 0.88.6
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-12-29 15:44:27 +05:45
Yunus M
d688399b91 fix: overflow issue in service page graphs (#4300) 2023-12-29 13:11:23 +05:30
Rajat Dabade
cfc239e3c9 refactor: added 3 days global timestamp (#4290)
* refactor: added 3 days global timestamp

* refactor: updated 3 days data in right container

* refactor: common function for calculate start and end time
2023-12-29 12:54:02 +05:30
Srikanth Chekuri
3572baa5eb fix: adjust the start and end more accurately (#4263)
* fix: adjust the start and end more accurately
Part of https://github.com/SigNoz/signoz/issues/1327

* chore: cache friendly timestamps
2023-12-29 12:35:22 +05:30
Rajat Dabade
ff26c5f69c fix: make fill gap persistent (#4302) 2023-12-29 12:23:27 +05:30
Srikanth Chekuri
9230f2442f fix: normalize label name to follow prometheus spec (#4264) 2023-12-28 20:22:42 +05:30
Raj Kamal Singh
7fed80b145 Fix: log pipelines contains and ncontains filters should be case insensitive (#4299)
* chore: add test validating contains and ncontains in pipeline filter are case insensitive

* chore: qb2expr: translate contains and ncontains to case insensitive comparison

* chore: minor cleanup
2023-12-28 19:44:17 +05:30
Yunus M
a268bb910c fix: update logic to handle step paths in Kubernetes APM flow (#4297)
* fix: update logic to handle step paths in kubernetes APM flow

* fix: don't reset service name on data source component mount
2023-12-28 18:30:41 +05:30
Rajat Dabade
fbbe0bef86 [Fix]: live view details modal disappear bug (#4249) 2023-12-28 16:02:55 +05:30
Raj Kamal Singh
bcd6ac47f7 Fix: Logs: Pipelines: add nil check for grok parser parseFrom field in generated collector config (#4286)
* chore: add test validating grok parser doesn't spam logs if parse from is missing

* chore: add nil check for grok parser parseFrom
2023-12-28 11:03:31 +05:30
Raj Kamal Singh
ec27916fa5 Fix: QS: Log Pipelines: generate correct nil checks for operators referencing fields like attributes["http.status.code"] (#4284)
* chore: add test validating that using paths like attributes["http.method"] works

* chore: refactor nil checks on processor fields generated for pipelines

* chore: get nil checks working on paths like attributes["http.method"]

* chore: use parsed AST for generating nil checks for add operator value expressions

* chore: some cleanup

* chore: some more cleanup

* chore: some more cleanup

* chore: some more cleanup

---------

Co-authored-by: Nityananda Gohain <nityanandagohain@gmail.com>
2023-12-28 10:31:36 +05:30
Srikanth Chekuri
263ac9fa5a fix: ignore timestamp from the subquery result for value panel (#4293) 2023-12-27 19:25:24 +05:30
Rajat Dabade
e3b2882811 [Fix]: scroll bar issue in table panel (#4043) 2023-12-27 10:56:36 +05:30
Rajat Dabade
63efb2b25a [Fix]: threshold table issue (#4247)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-12-27 10:38:22 +05:30
Srikanth Chekuri
788a38d39c chore: update CODEOWNERS (#4285) 2023-12-26 18:54:49 +05:30
Sanjib Kumar Sah
bff39daef0 fix: word overflow for large number in flamegraph (#4122)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-12-26 15:41:01 +05:30
CheetoDa
f2521b4c49 feat: onboarding flow updates and new flow addition (#4222)
* feat: onboarding flow updates and new flow addition

* feat: added reactjs files

* feat: added content for reactjs and others

* chore: implemented feedback

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
Co-authored-by: Yunus M <myounis.ar@live.com>
2023-12-26 10:43:55 +05:30
Ankit Nayan
16b846006a Merge pull request #4278 from SigNoz/release/v0.36.0
Release/v0.36.0
2023-12-22 15:18:38 +05:30
Prashant Shahi
0ea8e8e6b8 Merge branch 'develop' into release/v0.36.0 2023-12-22 15:12:32 +05:45
Prashant Shahi
da0ea7eb49 fix(dockerfile): copy invitation email templates for EE build (#4274)
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-12-22 14:55:30 +05:30
Prashant Shahi
ca41d7011e chore(signoz): 📌 pin versions: SigNoz 0.36.0, SigNoz OtelCol 0.88.4
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-12-22 14:37:29 +05:45
Vishal Sharma
f15e8f2fed Update new maintainers (#4277) 2023-12-22 12:46:21 +05:30
Yunus M
2e0fdbb498 feat: show rate limit warning in services page when total RPS > 100 (#4266)
* feat: show rate limit warning in services page when total rps > 100

* feat: update message

* feat: rate limit message should be shown only to cloud users on trail

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-12-22 00:51:37 +05:30
Vishal Sharma
585d6e2a21 chore: send event only if there are dashboards or alerts (#4253) 2023-12-21 19:06:13 +05:30
Vishal Sharma
d93cc767a6 chore: update active user event (#4271)
Merged on request by Visha
2023-12-21 19:05:21 +05:30
Prashant Shahi
a363b98657 feat(query-service): support for SMTP service (#4258)
* feat(query-service): support for SMTP service

Signed-off-by: Prashant Shahi <prashant@signoz.io>

* feat(query-service): smtp minor fixes

Signed-off-by: Prashant Shahi <prashant@signoz.io>

* chore: fix smtp and add email template

* chore: update template

* chore(smpt-service): configurable invite email template path

Signed-off-by: Prashant Shahi <prashant@signoz.io>

---------

Signed-off-by: Prashant Shahi <prashant@signoz.io>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-12-21 18:27:30 +05:30
Vishal Sharma
2031a014a7 Revert "Fix: lettercase bug in query-builder (#4120)" (#4255)
This reverts commit a6b6abf1a7.

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-12-21 13:36:56 +05:30
Raj Kamal Singh
43d5ee9651 FE: Log Detail View: Support for dots in log attributes (#4252)
* chore: add support for showing attrib names containing dots in log details

* chore: add support for field names with dot in filter actions

* chore: minor cleanup

* chore: add support for filtering by clicking fields with dots in log details
2023-12-21 13:21:20 +05:30
Nityananda Gohain
f8bb42a13c fix: dot support in attribute name (#4121)
* fix: dot support

* fix: column name updated for materialized columns

* fix: tests updated

* fix: comments updated

* fix: enrichment test updated

* fix: dont return underscore fields in the fields API

* fix: update fields function changed to support default instead of materialized

* fix: updated how formulas are built and test added

* fix: don't create index for bool attributes

* fix: support for limit queries updated
2023-12-21 12:11:35 +05:30
CheetoDa
1be4731710 feat: added frontend for newly addded flows (#4151)
* feat: added frontend for newly addded flows

* chore: added content for flows

* chore: updated content for dotnet docs

* chore: updated go instrumentation and http logs content

* fix: removed console log and return true

* fix: quickstart by default and cloudwatch logs

* fix: removed console log
2023-12-20 20:16:21 +05:30
Yunus M
90b8959045 feat: gh-4211: show copy and share invite link message next to pending invites (#4260)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-12-20 18:18:27 +05:30
Rajat Dabade
f487c1956b [Fix]: range issue in uplot charts (#4262)
* fix: range issue in uplot charts

* refactor: updated logic to strickly check is parsed value is number

* refactor: safe check for number value
2023-12-20 17:36:13 +05:30
Rajat Dabade
6b2f03d43f [Refactor]: Added tag and datatype in options for query builder (#3555)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-12-20 15:31:37 +05:30
Raj Kamal Singh
581bd07b35 Fix: query service: escape dollars in collector config generated for pipelines. (#4242)
* chore: add test validating pipeline config containing dollar works

* chore: collector simulator: use fileprovider with expandconverter like actual collector

* chore: get tests passing

* chore: take a configGenerator func in simulation and unify config generation logic

* fix: escape $ in config generated for log pipelines
2023-12-19 21:24:53 +05:30
Vikrant Gupta
c5cba68b53 fix: suggestions not populating without space (#4257) 2023-12-19 21:08:55 +05:30
Sanjib Kumar Sah
a6b6abf1a7 Fix: lettercase bug in query-builder (#4120)
* fix: lettercase bug in query-builder

* fix: suggesting similar value when entering diffrnt case value

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-12-19 16:03:30 +05:30
Yunus M
7526888886 feat: show trace details on hover (#4241)
* feat: show trace details on hover

* feat: handle sider anchor styles in dark and light mode
2023-12-18 17:03:38 +05:30
Vikrant Gupta
ce8fdd509b fix: [GH-3585]: operator suggestion should work on the substring typed in by the user (#4246)
* fix: [GH-3585]: operator suggestion logic

* fix: [GH-3585]: address review comments

* fix: [GH-3585]: address review comments
2023-12-18 13:51:39 +05:30
Nityananda Gohain
2baa6028b5 fix: enrichment for json in alerts and disable timestamp adjustment (#4240)
* fix: enrichment for json in alerts and disable timestamp adjustment

* fix: tests updated
2023-12-16 17:06:49 +05:30
Srikanth Chekuri
8e653f9500 fix: do not use grouping sets when there is no tags for group by (#4237) 2023-12-15 18:56:05 +05:30
Rajat Dabade
cb1a823f91 fix: the min data point as 0 in time series (#4203) 2023-12-15 17:44:13 +05:30
Yunus M
c0b0920901 Round off x axis max timestamp to T - 1 min and 0th second (#4238)
* feat: round of x axis max timestamp to t - 1 min and 0th second

* feat: set min width of time selection dropdown to 120px

* feat: update logic comment

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-12-15 17:29:54 +05:30
Rajat Dabade
77b4e71543 [refactor]: persistance of sorting and page in table (#4221) 2023-12-15 17:23:01 +05:30
Palash Gupta
9d44ce3ee2 feat: on create alerts query range format is called to fill the variables (#4204) 2023-12-15 17:08:35 +05:30
Yunus M
1d014ab4f7 Rearrange variables (#4187)
* feat: variable re-arrange

* feat: update variable update from dashboard description

* feat: update variable update from dashboard description

* feat: update custom variable dropdown values on change

* feat: handle dependent value updates to dashboard description

* feat: handle dependent 0th order variable update

* feat: update variable item test

* feat: transform variables data to support rearraging

* feat: update modal import

* feat: remove console logs

* feat: ts-ignore

* feat: show variable name in delete modal
2023-12-15 13:10:02 +05:30
Yunus M
418ab67d50 Uplot time range (#4144)
* feat: show range bound chart based on the selected time range

* feat: handle no data

* feat: show bigger point if only data point exists

* feat: show bigger point if only data point exists

* feat: widget ui fixes

* feat: no data - full view fix

* fix: show closed point on hover

* feat: handle widget time preference in case of dashboard, edit view, full view and chart preview
2023-12-14 22:56:25 +05:30
Vikrant Gupta
7efe907757 fix: [GH-3790]: timerange not working for different users (#4192) 2023-12-14 22:14:58 +05:30
Rajat Dabade
1d1154aa8c [Refactor]: added tooltip for graph manager (#4236) 2023-12-14 18:10:52 +05:30
Nityananda Gohain
a16fca6376 fix: remove timestamp roundup for logs list api call (#4229)
* fix: remove timestamp roundup for logs list api call

* fix: test updated
2023-12-14 16:52:02 +05:30
Rajat Dabade
9c1ea0cde9 refactor: pop for unsaved changes (#4188) 2023-12-14 11:43:02 +05:30
Nityananda Gohain
ec500831ef feat: upgrade clickhouse to 23.11.1 (#4225) 2023-12-14 11:22:20 +05:30
Prashant Shahi
fcbf82c2f3 Merge pull request #4232 from SigNoz/release/v0.35.1
Release/v0.35.1
2023-12-13 22:42:29 +05:30
Prashant Shahi
a805eb7533 chore(signoz): 📌 pin versions: SigNoz 0.35.1, SigNoz OtelCollector 0.88.3
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-12-13 21:13:09 +05:45
Vishal Sharma
a8edc4fd95 chore: better error handling in getAlertsInfo (#4230) 2023-12-13 19:12:35 +05:30
Vishal Sharma
c66c8c2823 chore: add new dashboard/alerts info events (#4214)
* chore: add new dashboard/alerts info events
2023-12-13 18:14:55 +05:30
Srikanth Chekuri
c7b59d4405 chore: update .github/CODEOWNERS (#3539)
* chore: update .github/CODEOWNERS

* chore: remove team
2023-12-13 17:53:18 +05:30
Vishal Sharma
f56b5cb971 fix: createPAT method to return id (#4078)
Update token expiry validations
2023-12-13 17:05:59 +05:30
Srikanth Chekuri
29b1344557 chore: add prepare query for cumulative/unspecified timeseries (#4166) 2023-12-13 16:40:17 +05:30
Rajat Dabade
55664872bd [Feat]: only clicked legend graph visible (#4226)
* refactor: only clicked legend graph visible

* refactor: fix graph manage toggle issue
2023-12-13 16:26:25 +05:30
Yunus M
221861230a feat: track channel click event in support page (#4217) 2023-12-13 01:18:19 +05:30
Yunus M
8b1a781f58 feat: pass abort signal to cancel api request on query-key change or … (#4193)
* feat: pass abort signal to cancel api request on query-key change or dashboard unmount

* fix: transformIgnorePatterns axios

* fix: remove axios types

* feat: handle error type from dashboardAPI response

* feat: remove console.log
2023-12-12 17:18:57 +05:30
Yunus M
b557ca5519 fix: use updated query value on test query, restrict direct commit to… (#4210)
* fix: use updated query value on test query, restrict direct commit to develop,main

* fix: reset error preview on success
2023-12-12 16:30:22 +05:30
Palash Gupta
e557ff273f test: metrics application test are added (#4137)
* test: metrics application test are added

* fix: getTopOperationList is moved under __mocks__
2023-12-12 14:16:06 +05:30
Yunus M
3c284fc9ee Revert "fix: variable edit flow - use updated query value on test query" (#4207)
This reverts commit bcebe050b1.
2023-12-12 11:38:06 +05:30
Yunus M
bcebe050b1 fix: variable edit flow - use updated query value on test query 2023-12-12 11:19:06 +05:30
Srikanth Chekuri
9360c61dca chore: update BuilderQuery struct and add PrepareTimeseriesFilterQuery (#4165) 2023-12-12 07:24:33 +05:30
guangwu
fb1dbdc05e chore: use bytes.Equal instead (#4201) 2023-12-11 18:45:47 +05:30
Rajat Dabade
6170b2c5dc [Refactor]: added percent 0 - 100 in yaxis for alerts (#4173) 2023-12-11 18:34:24 +05:30
Srikanth Chekuri
9826ab04b3 chore: add new endpoint for variable replacement (#4191)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-12-11 17:46:08 +05:30
Srikanth Chekuri
fd9566d471 fix: incorrect alert description and summary for prom rules (#4190) 2023-12-11 16:09:28 +05:30
Raj Kamal Singh
3a1e8d523a Fix: qs: allow saving pipelines without connected agents (#4189)
* chore: add test validating pipelines can be saved without connected agents

* chore: allow pipelines to be saved without connected agents
2023-12-09 10:17:06 +05:30
Gaurav Sharma
6dd34a7f29 Fix/2967 (#4071) 2023-12-08 12:37:19 +05:30
Avijeet Pandey
170e5e1686 fix(FE): Fixes the background color of the dashboards full screen view as per the mode selected i.e dark or light mode (#4175)
* fix: full screen bg color of graphs as per dark mode

* fix: colors from the constants
2023-12-08 11:53:56 +05:30
Prashant Shahi
16502feaad Merge pull request #4177 from SigNoz/release/v0.35.0
Release/v0.35.0
2023-12-06 22:15:19 +05:30
Prashant Shahi
09d579311e chore(signoz): 📌 pin versions: SigNoz 0.35.0
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-12-06 22:10:36 +05:45
dependabot[bot]
8072fede85 chore(deps): bump tj-actions/branch-names in /.github/workflows (#4164)
Bumps [tj-actions/branch-names](https://github.com/tj-actions/branch-names) from 5.1 to 7.0.7.
- [Release notes](https://github.com/tj-actions/branch-names/releases)
- [Changelog](https://github.com/tj-actions/branch-names/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/branch-names/compare/v5.1...v7.0.7)

---
updated-dependencies:
- dependency-name: tj-actions/branch-names
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-06 08:40:47 +05:30
Raj Kamal Singh
112783d618 Feat: fe: logs pipelines severity parsing processor (#4149) 2023-12-05 18:30:46 +05:30
Yunus M
4644b1c200 fix: custom variables options are not populated (#4154) 2023-12-05 16:09:50 +05:30
Yunus M
bb09c84679 fix: text formatting issues and upgrade button style updates (#4141) 2023-12-05 11:15:08 +05:30
Raj Kamal Singh
fc5f0fbf9e Feat: fe: logs pipelines timestamp parsing processor (#4106)
* chore: add processor config for time parsing processor

* chore: add select input and processor fields with enumerated options

* feat: set timestamp layout to default value when layout_type is changed

* chore: minor cleanup

* chore: some more cleanup

* chore: some more cleanup

* chore: get jest passing

* chore: normalize ts in pipelines previews input and output

* chore: some cleanup

* fix: set correct field id for timestamp format input
2023-12-04 15:57:14 +05:30
Ankit Nayan
d6f0559adc fix: ee/query-service/Dockerfile to reduce vulnerabilities (#4145)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6032386
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6032386
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6055795
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6055795

Co-authored-by: snyk-bot <snyk-bot@snyk.io>
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-12-03 08:00:33 +05:30
Yunus M
0d7f7df76c fix: pkg/query-service/Dockerfile to reduce vulnerabilities (#4146)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6032386
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6032386
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6055795
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6055795

Co-authored-by: snyk-bot <snyk-bot@snyk.io>
2023-12-03 07:53:15 +05:30
Vikrant Gupta
7104d8e0f5 feat: [GH-4093]: move the name to the left and the actions to the right for widget header (#4130) 2023-12-02 14:47:08 +05:30
Yunus M
a20693fa9f fix: add onboarding complete event (#4140) 2023-12-01 21:55:21 +05:30
Rajat Dabade
0b991331d7 [Fix]: threshold in alerts (#4074) 2023-12-01 18:16:25 +05:30
Raj Kamal Singh
aad44a1037 Feat: QS: logs pipelines severity parsing processor (#4132)
* chore: update test helper for making logs

* chore: add happy case test for severity parser

* feat: get severity parsing processor working and add more happy path tests

* chore: add test for validating severity parser doesn't spam collector logs

* chore: add if condition to generated severity_parser operators

* chore: add postablePipeline validation for severity parser

* chore: minor cleanup in tests

* chore: allow trace and fatal in severity mappings
2023-12-01 17:22:22 +05:30
Yunus M
3e29161fea fix: update logic for handling data for uplot charts (#4131)
* fix: update logic for handling data for uplot charts

* fix: hide tooltip if no tooltip values present

* fix: remove console log
2023-12-01 17:08:24 +05:30
Rajat Dabade
b616dca52d fix: the full view in service layer (#4133)
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-12-01 16:42:19 +05:30
dependabot[bot]
be519666a3 chore(deps): bump @adobe/css-tools from 4.3.1 to 4.3.2 in /frontend (#4134)
Bumps [@adobe/css-tools](https://github.com/adobe/css-tools) from 4.3.1 to 4.3.2.
- [Changelog](https://github.com/adobe/css-tools/blob/main/History.md)
- [Commits](https://github.com/adobe/css-tools/commits)

---
updated-dependencies:
- dependency-name: "@adobe/css-tools"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-01 11:14:14 +05:30
Rajat Dabade
a48edac13b fix: the default query issue in log (#4108) 2023-11-30 18:56:09 +05:30
Palash Gupta
0a77c7ab85 fix: onRun Query offset is made zero (#4083) 2023-11-30 18:41:26 +05:30
Prashant Shahi
9fb32acf6d ci(staging-deployment): ✏️ fix command to pull latest schema migrator image (#4123)
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-11-30 18:02:18 +05:30
Yunus M
b2d6d75eef feat: dashboard perf improvements (#4010)
* feat: dashboard perf improvements

* feat: remove console logs

* fix: remove console.log

* fix: update tests

* fix: update tests

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-11-30 13:56:49 +05:30
Prashant Shahi
07d126c669 Merge pull request #4114 from SigNoz/release/v0.34.4
Release/v0.34.4
2023-11-29 22:55:53 +05:30
Prashant Shahi
50d584cc89 chore: 📌 pin versions: SigNoz 0.34.4
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-11-29 22:47:59 +05:45
Raj Kamal Singh
1b6b3c2fdf Feat: query service: logs pipelines timestamp parsing processor (#4105)
* chore: relocate tests for trace and grok parsing processor

* chore: add test for timestamp parsing processor

* feat: update PipelineOperator model for time parser fields and get tests passing

* chore: add test cases for validating time parser fails silently on mismatched logs

* chore: add helper for generating regex for strptime layouts

* feat: time_parser ignore logs whose parseFrom value doesn't match strptime layout

* chore: escape regex special chars if any in the layout string before preparing regex

* chore: add operator.If on time_parser when using layout type epoch

* chore: finish up with operator.If on time_parser for  layout type

* chore: postable pipeline validation for time parser

* chore: some cleanup

* chore: some more cleanup

* chore: add validation for strptime layouts in postable pipelines

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-11-29 18:55:01 +05:30
Palash Gupta
1f0fdfd403 feat: element is made into focus and scrolled into view after edit/save (#4046) 2023-11-29 18:21:26 +05:30
Raj Kamal Singh
ae3b604cdc Fix: some pipelines UI fixes (#4112)
* fix: log pipelines: change incorrect placeholder for  fields

* fix: incorrect timestamp display in logs preview output
2023-11-29 17:18:32 +05:30
Palash Gupta
381f497b95 fix: queryTable is updated with newData (#4084) 2023-11-29 12:08:20 +05:30
Vikrant Gupta
8045c4e5ae feat: add pr template (#4102)
* feat: address review comments

---------

Co-authored-by: Prashant Shahi <prashant@signoz.io>
2023-11-29 11:04:48 +05:30
Nityananda Gohain
7451e885c3 feat: custom timeout and contextTimeout flag in response (#4022) 2023-11-29 09:10:30 +05:30
Vikrant Gupta
01df53074c fix: [GH-4075]: block action on the view section if the dashboard is locked (#4089)
* fix: [GH-4075]: block action on the view section if the dashboard is locked
2023-11-29 00:02:51 +05:30
Srikanth Chekuri
b6a79ab22c fix: use window function lagInFrame for rate calculation (#4068) 2023-11-28 19:16:08 +05:30
Yunus M
dae817640b fix: [GH-4097]: Fix missing values in chart tooltip (#4098) 2023-11-28 17:18:48 +05:30
Palash Gupta
16839eb7d3 fix: updated the form value on mount (#4076)
* fix: updated the form value on mount

* fix: isLoading is replaced isFetching
2023-11-28 13:44:25 +05:30
Palash Gupta
780a863943 feat: added the share link for view widget mode (#4052) 2023-11-28 13:33:39 +05:30
Srikanth Chekuri
5e0b6366cc chore: update rule create response (#4090) 2023-11-28 10:44:11 +05:30
Vikrant Gupta
8eb2b9e3d0 fix: [GH-4081]: no whitespace should appear when we remove hidden from body styles (#4092) 2023-11-28 08:30:37 +05:30
Yunus M
97ed163002 fix: sort tooltip value based on value and highlight on hover (#4059)
* fix: sort tooltip value based on value and highlight on hover

* fix: tsc issues
2023-11-27 18:07:15 +05:30
Vikrant Gupta
e18bb7d5bc fix: [3958]: restrict dashboard api call on other pages (#4066) 2023-11-27 17:49:22 +05:30
Yunus M
1e4cf2513c fix: update logic for handling data for uplot charts (#4070)
* fix: update logic for handling data for uplot charts

* fix: handle NaN data
2023-11-27 16:57:41 +05:30
Raj Kamal Singh
988ede7776 Fix/pipelines temp work around for supporting dots in resource keys (#4064)
* chore: logs pipelines: add test for validating workaround for working with dots in keys

* fix: temp workaround for supporting pipeline filters using names with dots converted to underscore
2023-11-26 12:57:23 +05:30
Rajat Dabade
d1acad8ee4 fix: the undefined threshold format issue (#4058) 2023-11-24 18:17:58 +05:30
Raj Kamal Singh
f5b1d4146f Fix: pipelines: string ops on missing attribs in pipeline filters should not spam warnings (#4049)
* chore: add test validating collector doesn't spam logs for string ops on missing attributes

* fix: pipelines filter: check if attrib is not nil before running string operator

* chore: do a nil check for all but == and != ops
2023-11-24 17:00:39 +05:30
Alex Bowers
feaac39e2a Dashboard full screen should be allowed regardless of whether dashboard is locked (#4055) 2023-11-24 14:50:45 +05:30
Palash Gupta
fc4cdea539 fix: dashboard delete is fixed and toast message is added (#4050)
* fix: dashboard delete is fixed and toast message is added

* fix: dashboard delete is fixed and toast message is added

* chore: message is updated
2023-11-24 11:51:26 +05:30
Vikrant Gupta
399d49b3c0 feat: added auth as pre-requisite for the other tests (#4031)
* feat: added auth as pre-requisite for the other tests

* feat: added navigation checks

* feat: added navigation checks
2023-11-24 00:40:15 +05:30
Yunus M
ec8a74d385 fix: new dashboard menu items are flickering (#4039) 2023-11-24 00:03:47 +05:30
Prashant Shahi
7c87310fa6 Merge pull request #4045 from SigNoz/release/v0.34.3
Release/v0.34.3
2023-11-23 22:08:49 +05:30
Prashant Shahi
349c4020f5 Merge branch 'develop' into release/v0.34.3 2023-11-23 21:48:59 +05:45
Srikanth Chekuri
92e2f1c467 fix: add legacy unit types and fix floating point issue (#4047) 2023-11-23 19:00:55 +05:30
Prashant Shahi
e3a89be86b chore: 📌 pin versions: SigNoz 0.34.3
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-11-23 16:56:45 +05:45
Yunus M
40090aaf12 fix: remove tooltip on chart cleanup (#4044) 2023-11-23 16:35:44 +05:30
Rajat Dabade
4009ac83fe [Feat]: threshold in table (#4002)
* feat: threshold in table

* refactor: updated the message

* chore: some css fixes
2023-11-23 15:32:06 +05:30
Yunus M
e7f9c3981b feat: show dashboard in full screen (#4040)
* fix: show dashboard in full screen

* fix: update label and remove border from grid in fullscreen mode
2023-11-23 14:10:34 +05:30
Vikrant Gupta
fe75f6347b feat: setup end to end test framework for playwright (#4003)
* feat: setup end to end test framework for playwright

* fix: remove github workflow
2023-11-23 01:05:15 +05:30
Prashant Shahi
bc72b5fcea Merge pull request #4029 from SigNoz/release/v0.34.2
Release/v0.34.2
2023-11-22 21:30:38 +05:30
Prashant Shahi
a54cf38e21 chore: 📌 pin versions: SigNoz 0.34.2
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-11-22 20:51:45 +05:45
Prashant Shahi
94d99ee0a4 Merge branch 'main' into release/v0.34.2 2023-11-22 20:51:13 +05:45
Rajat Dabade
c109636889 fix: where clause issue (#4023) 2023-11-22 20:32:25 +05:30
Palash Gupta
d9950d9223 fix: having white space is removed (#4025) 2023-11-22 19:50:04 +05:30
Srikanth Chekuri
a578f9509a fix: use correct operator for db and external APM metrics (#4026) 2023-11-22 18:41:56 +05:30
Raj Kamal Singh
b1e4ee1d26 fix: update condition for showing empty state vs showing pipeline list (#4017) 2023-11-22 15:54:12 +05:30
Rajat Dabade
31b07cc02c refactor: aggregrate api uses global time (#3911) 2023-11-22 13:43:29 +05:30
Yunus M
d42bf50ddb fix: docs updated according to feedback (#4011)
Co-authored-by: CheetoDa <Chitgupta24@gmail.com>
2023-11-21 20:01:14 +05:30
Prashant Shahi
93a11b2031 Merge pull request #4009 from SigNoz/release/v0.34.1
Release/v0.34.1
2023-11-21 18:25:01 +05:30
Prashant Shahi
af71474bec chore: 📌 pin versions: SigNoz OtelCollector 0.88.1, Schema Migrator 0.88.1
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-11-21 18:30:12 +05:45
Prashant Shahi
bc942d218b chore: 📌 pin versions: SigNoz v0.34.1
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-11-21 17:23:01 +05:45
Ankit Nayan
f2e7f09a32 Merge branch 'main' into develop 2023-11-21 17:06:11 +05:30
Palash Gupta
7e87df2d69 feat: Nan filtering is added (#4000)
* fix: handle nan in uplot

* feat: filter for nan is added for metrics

* feat: filter for nan is added for metrics

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-11-21 15:27:06 +05:30
Srikanth Chekuri
c0226ab584 fix: remove points with negative timestamps (#4007) 2023-11-21 14:49:34 +05:30
Joe Milton
84f2885533 fix: tab in license page aligned properly (#4006)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-11-21 13:49:51 +05:30
Yunus M
e58ecff19b chore: uplot file renames and reference updates (#4004) 2023-11-21 13:12:37 +05:30
Palash Gupta
f4ecfb510a fix: trace explorer and logs explorer export to dashboard is handled (#4001)
Co-authored-by: Yunus M <myounis.ar@live.com>
2023-11-21 00:52:53 +05:30
Vikrant Gupta
c4536f9069 feat: added dashboard list and create tests (#3989)
* feat: added dashboard list and create tests

* feat: added widget tests
2023-11-21 00:43:39 +05:30
Yunus M
2a55f3d680 feat: improve dashboard view user experience (#3654)
* feat: improve dashboard view user experience

* chore: dashboard ux is updated

* feat: add inter font and set font family in theme configuration

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-11-20 14:53:13 +05:30
Palash Gupta
5d6eea3045 feat: copy to clipboard start and end time added (#3995) 2023-11-20 11:30:49 +05:30
Yunus M
12029a6d90 feat: add open sans font and set font family in theme configuration (#3994)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-11-20 11:22:57 +05:30
Yunus M
4083970289 feat: update logic to generate x series for line series charts (#3993)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-11-20 10:56:33 +05:30
Yunus M
b3c0681a85 feat: reset selected envrironment, service name, framework on data source step mount (#3992) 2023-11-20 10:48:14 +05:30
Srikanth Iyengar
36aced6d1a fix: part of #1353, move db calls to prepared statement for checkttlstatusItem (#3976)
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-11-18 10:32:19 +05:30
Yunus M
bad69abcc2 Onboarding v2 (#3955)
* feat: onboarding v2

* feat: module steps container component

* feat: use onboarding context

* feat: restructure folders for onboarding

* feat: update data source utils and handle form value changes

* feat: fix tsx issues

* feat: remove stale code

* feat: handle validate data source step and other ui fixes

* feat: conditionally render steps inside modules

* feat: update onboarding for ror

* feat: refactoring

* feat: generate file path to fetch md doc

* feat: delete old module component files and move analytics utils to custom hook

* feat: handle environment not selected state

* feat: docs file structure for onboarding (#3975)

* feat: replace analytics util with hooks

* feat: delete apm flask kubernetes files and reference

* feat: update analytics events

* Onboarding docs v2 (#3988)

* feat: added content to markdown files

* feat: separate filepath constants for apm, logs , infra

* feat: map key and filepath for logs

* feat: mapped inframonitoring file paths

* feat: minor updates

* feat: remove console.log

---------

Co-authored-by: Calm-Rock <Chitgupta24@gmail.com>

* feat: ignore file path fetch error

---------

Co-authored-by: Calm-Rock <Chitgupta24@gmail.com>
2023-11-17 20:08:04 +05:30
Vikrant Gupta
d091d90d66 feat: trace explorer page end to end test (#3960)
* feat: added trace explorer tests

* feat: code refactor

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-11-17 18:14:10 +05:30
Vishal Sharma
29bfdb8909 chore: add new telemetry events and heartbeat events to saas (#3985) 2023-11-17 16:18:31 +05:30
Raj Kamal Singh
31b5635339 Chore: logs pipelines help in UI (#3971)
* chore: logs pipelines: add help text with link to pipeline docs

* chore: add logs pipelines list empty state with help video and link to docs

* chore: minor cleanup

* chore: update test snapshot

* chore: dont show table & filter in pipeline lists empty state

* chore: add sandbox constraints to logs pipelines empty state video iframe

* chore: update test snapshot
2023-11-17 14:01:28 +05:30
Ankit Nayan
73fc262f04 Merge pull request #3982 from SigNoz/release/v0.34.0
Release/v0.34.0
2023-11-17 01:00:06 +05:30
Prashant Shahi
dc23368f6e chore: 📌 pin versions: SigNoz 0.34.0, SigNoz OtelCollector 0.88.0, tidy go modules
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-11-16 22:04:22 +05:45
Rajat Dabade
75526c6de5 [Fix]: threshold dashboard fixes (#3980) 2023-11-16 15:27:48 +05:30
Vishal Sharma
5b419cb668 fix: improve user telemetry (#3972)
* fix: improve user telemetry
- move GetEmailFromJwt to common function
- update AttachJwtToContext() to use standard way of attaching value to context
- update userEmail in every possible sendEvent call
- send groupId in sendEvent call for SaaS operator analytics

* chore: added DEFAULT_CLOUD_EMAIL const

* chore: add AttachJwtToContext to analytics middleware

* test: added AttachJwtToContext to logs pipelines
2023-11-16 15:11:38 +05:30
Joe Milton
d8a8430a5b feat(dashboard): enable cmd+click for dashboard name in list (#3947) 2023-11-16 13:12:43 +05:30
Rajat Dabade
dc7a55e871 [Fix]: Threshold in dashboard fixes (#3979)
* fix: the extra showcase for text and background

* fix: css issue for select
2023-11-16 12:51:35 +05:30
Rajat Dabade
9333fdcd0b [Feat]: Uplot Threshold in Time Series. (#3974)
* refactor: resolve merge conflict

* refactor: added support to value conversion

* refactor: linter fixes

* refactor: build fixes
2023-11-15 19:17:06 +05:30
Yunus M
58ccbdbec4 Feat/fill span gaps reset (#3973)
* feat: fill span gaps is added

* chore: build is fixed

* chore: get fill spans is updated

* chore: console is removed

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-11-15 18:25:02 +05:30
Rajat Dabade
12819113c1 [Feat]: Threshold in dashboard for Value Component (#3949)
* feat: done with the basic design

* refactor: started working with functionality

* refactor: done with saving the thresholds

* refactor: done with coloring and conflicting threshold in value chart

* refactor: done with the backgound color and text

* refactor: done with unit in value graphs

* refactor: done with precedence and drag and drop

* refactor: removed the unwanted console

* chore: updated snapshot and test

* refactor: support for dark mode

* refactor: done with the review changes

* refactor: removed the extra created file

* refactor: tsc fixes

* refactor: updated border color

* refactor: updated required mark

* refactor: added missing props

* refactor: tsc fixes

* refactor: addressed review comments
2023-11-15 17:14:09 +05:30
Yunus M
37f61ebe60 feat: use error boundary lib and setup fallback component (#3970)
* feat: use error boundary lib and setup fallback component

* feat: move text to translations
2023-11-15 16:46:20 +05:30
Palash Gupta
f2f89eb38b feat: uplot graph is added and some re-rendering is reduced (#3771)
* feat: uplot graph is added and some re-rendering is reduced

* chore: uplot is updated

* feat: changes for the graph is updated

* refactor: added y-axis unit in uplot graph (#3818)

* refactor: added y-axis unit in uplot graph

* refactor: removed the ticks stroke from both access

* feat: create tooltip plugin for uplot charts (#3823)

* feat: create tooltip plugin for uplot charts

* feat: show labels in legends section

---------

Co-authored-by: Yunus M <myounis.ar@live.com>

* feat: uplot points is handled  (#3817)

* chore: resize is updated

* chore: uplot chart dark mode is updated

* chore: widget is updated

* chore: options is updated

* chore: value panel is updated

* feat: uplot chart is updated

* feat: onDrag is updated

* feat: data for graph is updated

* feat: alert section is fixed

* feat: not found is updated

* feat: fix dashboard title section and other uplot parity issues (#3839)

* feat: fix dashboard title section and other uplot parity issues

* feat: update scrollbar style for legend container

* chore: initial width is updated

* feat: onlcick is updated

* feat: widget full view fixes (#3847)

Co-authored-by: Palash Gupta <palashgdev@gmail.com>

* feat: show labels in tooltip overlay (#3867)

* chore: memo is added

* feat: toggle is updated

* fix: Tooltip values is now fixed (#3894)

* chore: tooltip is updated

* chore: avoided the compute based on show

* chore: tooltip data is updated

* feat: resize graph based on the y axis max label length (#3895)

* chore: build is in progress to fix

* [Feat]: Full View  (#3896)

* fix: initial setup for full view done

* refactor: done with the graph manager logic

* refactor: done with the toggle issue in full view

* refactor: done with toggle of data

* refactor: done with legend to table mapping

* refactor: ts error

* chore: utils is updated

* refactor: updated types

* fix: option type fix

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>

* feat: use spline renderer to plot curved line graphs, full view impor… (#3919)

* feat: use spline renderer to plot curved line graphs, full view imporvements

* feat: increase min height for panel

* chore: move code to utils and plugins in uplot folder

* chore: update tooltip styles

* fix: add panel issue in dashboard (#3920)

* fix: update on click plugin opts import path

* feat: replace time series graph in logs explorer and trace explorer with uplot (#3925)

* feat: alert threshold is added (#3931)

* feat: uplot styles are fixed (#3941)

* Fix/app dex aligment (#3944)

* feat: uplot styles are fixed

* fix: app dex aligment

* fix: full view after saving is fixed

* feat: css is updated (#3948)

* feat: on click handler position - factor in the padding on top and left

* fix: timestamp for start and end is updated for view trace (#3966)

* fix: timestamp for start and end is updated for view trace

* chore: timestamp is added

* fix: loading over flow is fixed (#3969)

---------

Co-authored-by: Rajat Dabade <rajat@signoz.io>
Co-authored-by: Yunus M <myounis.ar@live.com>
2023-11-15 15:33:45 +05:30
Raj Kamal Singh
a99d7f09a1 Chore: logs pipelines UI telemetry (#3964)
* chore: emit event when user saves pipelines

* chore: emit tracking event for entered edit mode

* chore: emit tracking event for clicking add new processor

* chore: emit tracking event for clicking preview pipeline btn

* chore: address PR feedback
2023-11-15 14:38:30 +05:30
Vikrant Gupta
2ae75e6196 feat: happy flow for services from list view to all the three details tab rendering the correct tables (#3942)
* feat: complete services flow

* feat: complete all the three tab flows

* feat: address review comments
2023-11-14 18:06:17 +05:30
Srikanth Chekuri
4a042fa413 feat: add time-series-limit config option 2023-11-14 02:58:59 +05:30
Raj Kamal Singh
f86fc03fd6 fix: adding 2 pipeline processors with same name should not break the UI (#3943)
* fix: ensure pipeline processor ids derived from name are unique

* fix: update snapshots to get jest passing

* chore: use uuid for processor ids
2023-11-13 15:29:36 +05:30
Palash Gupta
5a9f626da5 feat(FE): dashboard alerts is added (#3908)
* feat: create menu items is added in the service application widgets

* chore: filter query is updated

* fix: build is fixed

* feat: selected query is updated

* chore: create alerts is updated

* feat: dashboard alerts is updated

* chore: spacing is updated

* feat: dashboard to alerts is updated

* fix: build is fixed

* feat: alert query options is updated

* chore: menu list is updated for tabel panel

---------

Co-authored-by: Rajat Dabade <rajat@signoz.io>
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-11-13 13:54:31 +05:30
Lars Lehtonen
758013d7cd pkg/query-service/app: fix dropped error (#3842)
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-11-10 17:51:17 +05:30
Srikanth Chekuri
ddc3cc4911 chore: dashboards to alerts creation support in query-service (#3924) 2023-11-10 17:43:19 +05:30
CheetoDa
6b2f857a12 docs: added ror onboarding docs (#3927)
* docs: added ror onboarding docs

* feat: add ror docs

* feat: update ror details in connection status

---------

Co-authored-by: Yunus A M <myounis.ar@live.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-11-10 13:09:25 +05:30
Palash Gupta
30b0d42604 fix: try Signoz is visible on success (#3906) 2023-11-10 11:16:42 +05:30
Vikrant Gupta
88aabb2060 feat: added services page playwright tests (#3928)
* feat: added services page playwright tests

* feat: added empty page test
2023-11-09 20:35:07 +05:30
Joe Milton
f939d41acd fix(tags): tag modification in triggered alerts page (#3873)
Co-authored-by: Yunus M <myounis.ar@live.com>
2023-11-09 20:16:05 +05:30
Nityananda Gohain
d165f727ac fix: trace_parser removed (#3937) 2023-11-09 18:35:52 +05:30
Rajat Dabade
e4ef137c72 refactor: global time range for promql query (#3935) 2023-11-09 16:00:02 +05:30
Palash Gupta
dda01678e8 fix: page break in Services overview tab (#3749)
* fix: null check

* fix: metrics check is updated
2023-11-06 12:16:15 +05:30
Raj Kamal Singh
3e65543b5f Fix: resource filters should work in logs pipelines (#3889)
* chore: add test validating resource based filters work in logs pipelines

* fix: get resource filters working in logs pipelines
2023-11-03 18:42:03 +05:30
Raj Kamal Singh
050b866173 chore: return warning logs too from collector simulator (#3888)
* chore: return warning logs too from collector simulator

* chore: also return collector logs in preview API response to help with debugging

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-11-03 17:41:09 +05:30
Yunus M
0906886e9a feat: dashboard lock feature (#3880)
* feat: dashboard lock feature

* feat: update API method and minor ui updates

* feat: update API and author logic

* feat: update permissions for author role

* feat: use strings and remove console logs
2023-11-03 17:27:09 +05:30
Srikanth Chekuri
8371670512 chore: dashboard locking ee query-service (#3890) 2023-11-03 15:45:45 +05:30
Ankit Nayan
123f2e7d52 Merge branch 'main' into develop 2023-11-03 00:00:54 +05:30
Ankit Nayan
0ab09c1c67 Merge pull request #3882 from SigNoz/release/v0.33.1
Release/v0.33.1
2023-11-02 23:59:26 +05:30
Prashant Shahi
9f5039dbf3 chore: 📌 pin versions: SigNoz 0.33.1
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-11-02 23:36:09 +05:45
Srikanth Chekuri
5e349d8294 chore: dashboard locking ee query-service (#3856)
* chore: dashboard locking ee query-service

* chore: remove print statements

* chore: remove unused imports

* chore: no one is allowed to edit/delete the locked dashboard

---------

Co-authored-by: Srikanth Chekuri <srikanth@Srikanths-MacBook-Pro.local>
2023-11-02 22:52:50 +05:30
Rajat Dabade
b5654c8bfa [Fix]: the height issue for resizable tables (#3875) 2023-11-02 22:25:22 +05:30
Rajat Dabade
71e487dc0c fix: full view chart label and checkbox issue (#3879) 2023-11-02 20:32:01 +05:30
Palash Gupta
2d60805b28 fix: empty widget is handled (#3830)
* fix: empty widget is updated

* chore: widget is updated

* fix: handling is updated
2023-11-02 17:00:34 +05:30
Ankit Nayan
7603e0ebe0 Merge pull request #3872 from SigNoz/release/v0.33.0
Release/v0.33.0
2023-11-01 23:30:32 +05:30
Prashant Shahi
1e8a8d19ea chore: 📌 pin versions: SigNoz 0.33.0, SigNoz OtelCollector 0.79.13
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-11-01 23:22:57 +05:45
Rajat Dabade
092d164d55 refactor: global time range downdown for alert edit page (#3751)
* refactor: global time range downdown for alert edit page

* refactor: respect global time range for alerts

* refactor: some ui fixes

* refactor: added global time range in alert new page

* fix: custom time selection in alert

* fix: the run query works

* refactor: remove the routes pipeline

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
Co-authored-by: Ankit Nayan <ankit@signoz.io>
2023-11-01 22:47:27 +05:30
Rajat Dabade
0400d5378b [Fix]: the loading state based on the time interval (#3755)
* fix: the loading state based on the time interval

* fix: failing of query-range api
2023-11-01 22:36:04 +05:30
Raj Kamal Singh
626da7533e Fix: log pipelines: generated operators should have appropriate if condition to avoid spamming collector logs (#3870)
* chore: experiment with using a tmp file for getting collector logs in simulator

* chore: collector simulator: cleaned up tmp file based collector logs capture

* chore: add test validating regex proc doesn't error for logs that dont match

* chore: return collector error logs from pipeline preview API

* chore: add test validating regex processor doesn't log errors for mismatched logs

* chore: add if condition for generated regex processors

* chore: add test case validating json parser ignore non json logs

* chore: add if condition for operator generated for json parser

* chore: add test case validating move processor ignores logs with missing field

* chore: add if condition for operator generated for move

* chore: add test case validating copy processor ignores logs with missing field

* chore: add if condition for operator generated for copy

* chore: add test case validating remove processor ignores logs with missing field

* chore: add if condition for operator generated for remove

* chore: log pipelines: ensuring json parser ignores log if json field is missing

* chore: log pipelines: ensure regex parser ignores log if field is missing
2023-11-01 22:12:35 +05:30
Prashant Shahi
bff7142a61 ci(staging-deployment): 👷 pull latest main tagged schema-migrator docker image (#3869)
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-11-01 21:30:40 +05:30
Raj Kamal Singh
ed3017d247 chore: add logs pipelines nav and update logs pipelines title and routes (#3858)
* chore: update logs pipelines title and routes

* chore: add nav for logs pipelines

* feat: debounced pipelines sarch on change, navigation text changes

* fix: get lint passing

* fix: update snapshots for tests

---------

Co-authored-by: Yunus A M <myounis.ar@live.com>
2023-11-01 20:37:27 +05:30
Rajat Dabade
ec3eba612c [Refactor]: Dynamic Columns PR (#3852)
* fix: remove the space and fix the classname

* refactor: made the dynamicColumnsTable-items responsive

* fix: setcolumndata to a separate function

* fix: handle invalid CreatedOrUpdateTime

* fix: hyphenate classname and bme

* refactor: move the implementation to separate component

* refactor: removed the bydefault render

* refactor: remove render

* refactor: removed unwanted imports

* fix: remove the space and fix the classname

* refactor: made the dynamicColumnsTable-items responsive

* fix: setcolumndata to a separate function

* fix: handle invalid CreatedOrUpdateTime

* fix: hyphenate classname and bme

* refactor: move the implementation to separate component

* refactor: removed the bydefault render

* refactor: remove render

* fix: the classname
2023-11-01 18:26:41 +05:30
Nityananda Gohain
b958a06ba0 fix: support for dash in path name for json query (#3861) 2023-11-01 18:13:28 +05:30
Rajat Dabade
64f0ff05f9 [Feat]: Download as CSV and Execl and Search option for key-operation table (#3848)
* refactor: done with the download option for key-operation

* refactor: added search option for key operation metrics

* refactor: done with the download option for key-operation

* refactor: added search option for key operation metrics

* refactor: updated downloadable data

* refactor: updated downloadable data for metrics key operation

* refactor: updated the data

* refactor: map with the correct value for export

* refactor: updated downloabable data for metrics

* refactor: updated the data for metrics

* refactor: added safety check

---------

Co-authored-by: Ankit Nayan <ankit@signoz.io>
2023-11-01 17:53:31 +05:30
Vishal Sharma
f94a5f4481 fix: ignore reload identity calls (#3862) 2023-11-01 13:31:17 +05:30
Raj Kamal Singh
27869f03bd Fix: log pipelines: only one of the trace parser fields is required (#3857)
* chore: update trace parser form field placeholders

* fix: trace parser form: only one of the fields is required
2023-11-01 11:00:31 +05:30
Raj Kamal Singh
9c21449239 chore: empty out trace parser fields if parseFrom is empty (#3850) 2023-11-01 10:10:36 +05:30
Yunus M
991e39aad3 fix: 404 on clicking version menu item in side nav (#3853) 2023-11-01 01:26:08 +05:30
Rajat Dabade
eddb607c9c [Fix]: added the darktheme support for Action Column in Alerts Listing Table. (#3844)
* refactor: added the darktheme support

* fix: typo

---------

Co-authored-by: Ankit Nayan <ankit@signoz.io>
2023-11-01 00:43:22 +05:30
Nityananda Gohain
3341cb7396 feat: boolean attribute support (#3816)
* feat: boolean attribute support

* fix: comment updated

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-10-31 15:06:07 +05:30
Raj Kamal Singh
4ca1e34378 Fix: Log pipelines deployment status unknown (#3838)
* fix: fe: log pipelines: label and icon for deploy status 'UNKNOWN'

* fix: handle scenarios when response.payload?.pipelines is undefined (eg: post delete all)
2023-10-31 11:25:41 +05:30
Raj Kamal Singh
658a9cc11b fix: only latest agent config versions can have a pending deployment (#3836) 2023-10-31 10:36:25 +05:30
Nityananda Gohain
4ef973ceb6 feat: default trace_parser updated (#3782)
* feat: default trace_parser updated

* fix: regex updated
2023-10-30 21:28:21 +05:30
dependabot[bot]
bbfaad15c2 chore(deps): bump @babel/traverse from 7.21.4 to 7.23.2 in /frontend (#3756)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.21.4 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-29 18:20:13 +05:30
Raj Kamal Singh
45ead71359 Fix: get log pipelines trace parser working (#3822)
* chore: add trace parser fields to log pipeline ProcessorData interface

* chore: update trace parsing processor form field configs

* chore: logs pipeline preview: better display of sample logs when too few logs in sample

* fix: log pipelines: get tests passing: remove name prop passed to antd input
2023-10-29 17:46:08 +05:30
Raj Kamal Singh
79aef73767 Fix: Query Service: get trace parser working in log parsing pipelines (#3820)
* chore: add test for ensuring pipeline previews work for trace parser processors

* chore: updates to trace parser validation in postable pipelines

* chore: extract auth.randomHex into utils.RandomHex for reuse

* chore: get trace parser preview test passing

* chore: start with JSON serialized trace parser in test to cover deserialization

* chore: address PR feedback
2023-10-29 16:58:31 +05:30
Rajat Dabade
fc49833c9f [Feat]: Dynamic columns in tables (#3809)
* feat: added dropdown in alert list table

* refactor: done with combining actions

* feat: done with label and dynamic table

* feat: dynamic column in table

* chore: show all label on hover

* refactor: create to created timestamp - highlighted action

* refactor: storing the column data in localstorage
2023-10-27 21:09:23 +05:30
Yunus M
b34eafcab1 fix: ee/query-service/Dockerfile to reduce vulnerabilities (#3805)
Co-authored-by: snyk-bot <snyk-bot@snyk.io>
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-10-27 00:09:19 +05:30
dependabot[bot]
ed4ba1aa24 chore(deps): bump google.golang.org/grpc from 1.57.0 to 1.57.1 (#3808)
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.57.0 to 1.57.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.57.0...v1.57.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-26 23:58:35 +05:30
Raj Kamal Singh
f427bac993 Fix: grok parser in pipeline previews (#3810)
* chore: add test for previewing pipeline with grok parser

* chore: import grok parser in logparsing preview to ensure its a registered logtransform op

* chore: add dependencies for grok parsing operator
2023-10-26 19:37:13 +05:30
Yunus M
7de3cec477 fix: update logic to conditionally show Get Started and Billing routes (#3807) 2023-10-26 18:39:04 +05:30
Ankit Nayan
856c04220f fix: pkg/query-service/Dockerfile to reduce vulnerabilities (#3811)
Co-authored-by: snyk-bot <snyk-bot@snyk.io>
2023-10-26 13:46:26 +05:30
Yunus M
6a8096b8d7 feat: santize identity payload and pass source to identity and group calls (#3804) 2023-10-26 01:58:24 +05:30
Prashant Shahi
9bad663c4f Merge pull request #3801 from SigNoz/release/v0.32.1
Release/v0.32.1
2023-10-26 00:15:52 +05:45
1092 changed files with 46190 additions and 7925 deletions

9
.github/CODEOWNERS vendored
View File

@@ -1,13 +1,10 @@
# CODEOWNERS info: https://help.github.com/en/articles/about-code-owners
# Owners are automatically requested for review for PRs that changes code
# that they own.
* @ankitnayan
/frontend/ @palashgdev @YounixM
/frontend/ @YounixM
/frontend/src/container/MetricsApplication @srikanthccv
/frontend/src/container/NewWidget/RightContainer/types.ts @srikanthccv
/deploy/ @prashant-shahi
/sample-apps/ @prashant-shahi
**/query-service/ @srikanthccv
Makefile @srikanthccv
go.* @srikanthccv
.git* @srikanthccv
.github @prashant-shahi

17
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,17 @@
### Summary
<!-- ✍️ A clear and concise description...-->
#### Related Issues / PR's
<!-- ✍️ Add the issues being resolved here and related PR's where applicable -->
#### Screenshots
NA
<!-- ✍️ Add screenshots of before and after changes where applicable-->
#### Affected Areas and Manually Tested Areas
<!-- ✍️ Add details of blast radius and dev testing areas where applicable-->

View File

@@ -34,7 +34,7 @@ jobs:
id: short-sha
- name: Get branch name
id: branch-name
uses: tj-actions/branch-names@v5.1
uses: tj-actions/branch-names@v7.0.7
- name: Set docker tag environment
run: |
if [ '${{ steps.branch-name.outputs.is_tag }}' == 'true' ]; then
@@ -78,7 +78,7 @@ jobs:
id: short-sha
- name: Get branch name
id: branch-name
uses: tj-actions/branch-names@v5.1
uses: tj-actions/branch-names@v7.0.7
- name: Set docker tag environment
run: |
if [ '${{ steps.branch-name.outputs.is_tag }}' == 'true' ]; then
@@ -127,7 +127,7 @@ jobs:
id: short-sha
- name: Get branch name
id: branch-name
uses: tj-actions/branch-names@v5.1
uses: tj-actions/branch-names@v7.0.7
- name: Set docker tag environment
run: |
if [ '${{ steps.branch-name.outputs.is_tag }}' == 'true' ]; then
@@ -176,7 +176,7 @@ jobs:
id: short-sha
- name: Get branch name
id: branch-name
uses: tj-actions/branch-names@v5.1
uses: tj-actions/branch-names@v7.0.7
- name: Set docker tag environment
run: |
if [ '${{ steps.branch-name.outputs.is_tag }}' == 'true' ]; then

View File

@@ -29,6 +29,7 @@ jobs:
export PATH="/usr/local/go/bin/:$PATH" # needed for Golang to work
docker system prune --force
docker pull signoz/signoz-otel-collector:main
docker pull signoz/signoz-schema-migrator:main
cd ~/signoz
git status
git add .

11
.gitignore vendored
View File

@@ -37,7 +37,7 @@ frontend/src/constants/env.ts
**/locust-scripts/__pycache__/
**/__debug_bin
frontend/.env
.env
pkg/query-service/signoz.db
pkg/query-service/tests/test-deploy/data/
@@ -53,3 +53,12 @@ ee/query-service/tests/test-deploy/data/
bin/
*/query-service/queries.active
# e2e
e2e/node_modules/
e2e/test-results/
e2e/playwright-report/
e2e/blob-report/
e2e/playwright/.cache/
e2e/.auth

View File

@@ -11,7 +11,6 @@
<img alt="tweet" src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a>
</p>
<h3 align="center">
<a href="https://signoz.io/docs"><b>Dokumentation</b></a> &bull;
<a href="https://github.com/SigNoz/signoz/blob/develop/README.md"><b>Readme auf Englisch </b></a> &bull;
@@ -40,12 +39,13 @@ SigNoz hilft Entwicklern, Anwendungen zu überwachen und Probleme in ihren berei
👉 Einfache Einrichtung von Benachrichtigungen mit dem selbst erstellbaren Abfrage-Builder.
##
### Anwendung Metriken
![application_metrics](https://user-images.githubusercontent.com/83692067/226637410-900dbc5e-6705-4b11-a10c-bd0faeb2a92f.png)
### Verteiltes Tracing
<img width="2068" alt="distributed_tracing_2 2" src="https://user-images.githubusercontent.com/83692067/226536447-bae58321-6a22-4ed3-af80-e3e964cb3489.png">
<img width="2068" alt="distributed_tracing_1" src="https://user-images.githubusercontent.com/83692067/226536462-939745b6-4f9d-45a6-8016-814837e7f7b4.png">
@@ -62,22 +62,18 @@ SigNoz hilft Entwicklern, Anwendungen zu überwachen und Probleme in ihren berei
![exceptions_light](https://user-images.githubusercontent.com/83692067/226637967-4188d024-3ac9-4799-be95-f5ea9c45436f.png)
### Alarme
<img width="2068" alt="alerts_management" src="https://user-images.githubusercontent.com/83692067/226536548-2c81e2e8-c12d-47e8-bad7-c6be79055def.png">
<br /><br />
## Werde Teil unserer Slack Community
Sag Hi zu uns auf [Slack](https://signoz.io/slack) 👋
<br /><br />
## Funktionen:
- Einheitliche Benutzeroberfläche für Metriken, Traces und Logs. Keine Notwendigkeit, zwischen Prometheus und Jaeger zu wechseln, um Probleme zu debuggen oder ein separates Log-Tool wie Elastic neben Ihrer Metriken- und Traces-Stack zu verwenden.
@@ -93,7 +89,6 @@ Sag Hi zu uns auf [Slack](https://signoz.io/slack) 👋
<br /><br />
## Wieso SigNoz?
Als Entwickler fanden wir es anstrengend, uns für jede kleine Funktion, die wir haben wollten, auf Closed Source SaaS Anbieter verlassen zu müssen. Closed Source Anbieter überraschen ihre Kunden zum Monatsende oft mit hohen Rechnungen, die keine Transparenz bzgl. der Kostenaufteilung bieten.
@@ -116,12 +111,10 @@ Wir unterstützen [OpenTelemetry](https://opentelemetry.io) als Bibliothek, mit
- Elixir
- Rust
Hier findest du die vollständige Liste von unterstützten Programmiersprachen - https://opentelemetry.io/docs/
<br /><br />
## Erste Schritte mit SigNoz
### Bereitstellung mit Docker
@@ -138,7 +131,6 @@ Bitte folge den [hier](https://signoz.io/docs/deployment/helm_chart) aufgelistet
<br /><br />
## Vergleiche mit bekannten Tools
### SigNoz vs Prometheus
@@ -179,7 +171,6 @@ Wir haben Benchmarks veröffentlicht, die Loki mit SigNoz vergleichen. Schauen S
<br /><br />
## Zum Projekt beitragen
Wir ❤️ Beiträge zum Projekt, egal ob große oder kleine. Bitte lies dir zuerst die [CONTRIBUTING.md](CONTRIBUTING.md), durch, bevor du anfängst, Beiträge zu SigNoz zu machen.
@@ -197,6 +188,8 @@ Du bist dir nicht sicher, wie du anfangen sollst? Schreib uns einfach auf dem #c
#### Frontend
- [Palash Gupta](https://github.com/palashgdev)
- [Yunus M](https://github.com/YounixM)
- [Rajat Dabade](https://github.com/Rajat-Dabade)
#### DevOps
@@ -204,16 +197,12 @@ Du bist dir nicht sicher, wie du anfangen sollst? Schreib uns einfach auf dem #c
<br /><br />
## Dokumentation
Du findest unsere Dokumentation unter https://signoz.io/docs/. Falls etwas unverständlich ist oder fehlt, öffne gerne ein Github Issue mit dem Label `documentation` oder schreib uns über den Community Slack Channel.
<br /><br />
## Gemeinschaft
Werde Teil der [slack community](https://signoz.io/slack) um mehr über verteilte Einzelschritt-Fehlersuche, Messung von Systemzuständen oder SigNoz zu erfahren und sich mit anderen Nutzern und Mitwirkenden in Verbindung zu setzen.

View File

@@ -199,10 +199,13 @@ Not sure how to get started? Just ping us on `#contributing` in our [slack commu
#### Frontend
- [Palash Gupta](https://github.com/palashgdev)
- [Yunus M](https://github.com/YounixM)
- [Rajat Dabade](https://github.com/Rajat-Dabade)
#### DevOps
- [Prashant Shahi](https://github.com/prashant-shahi)
- [Dhawal Sanghvi](https://github.com/dhawal1248)
<br /><br />

View File

@@ -19,7 +19,7 @@
<a href="https://twitter.com/SigNozHq"><b>Twitter</b></a>
</h3>
##
##
SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可以使用 SigNoz 实现如下能力:
@@ -67,7 +67,7 @@ SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可
## 加入我们 Slack 社区
来 [Slack](https://signoz.io/slack) 和我们打招呼吧 👋
来 [Slack](https://signoz.io/slack) 和我们打招呼吧 👋
<br /><br />
@@ -83,7 +83,7 @@ SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可
- 通过 服务名、操作方式、延迟、错误、标签/注释 过滤 traces 数据
- 通过聚合 trace 数据而获得业务相关的 metrics。 比如你可以通过 `customer_type: gold` 或者 `deployment_version: v2` 或者 `external_call: paypal` 获取错误率和 P99 延迟数据
- 通过聚合 trace 数据而获得业务相关的 metrics。 比如你可以通过 `customer_type: gold` 或者 `deployment_version: v2` 或者 `external_call: paypal` 获取错误率和 P99 延迟数据
- 原生支持 OpenTelemetry 日志,高级日志查询,自动收集 k8s 相关日志
@@ -101,7 +101,7 @@ SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可
我们想做一个自托管并且可开源的工具,像 DataDog 和 NewRelic 那样, 为那些担心数据隐私和安全的公司提供第三方服务。
作为开源的项目,你完全可以自己掌控你的配置、样本和更新。你同样可以基于 SigNoz 拓展特定的业务模块。
作为开源的项目,你完全可以自己掌控你的配置、样本和更新。你同样可以基于 SigNoz 拓展特定的业务模块。
### 支持的编程语言:
@@ -153,9 +153,9 @@ Jaeger 仅仅是一个分布式追踪系统。 但是 SigNoz 可以提供 metric
而且, SigNoz 相较于 Jaeger 拥有更对的高级功能:
- Jaegar UI 不能提供任何基于 traces 的 metrics 查询和过滤。
- Jaegar UI 不能提供任何基于 traces 的 metrics 查询和过滤。
- Jaeger 不能针对过滤的 traces 做聚合。 比如, p99 延迟的请求有个标签是 customer_type='premium'。 而这些在 SigNoz 可以轻松做到。
- Jaeger 不能针对过滤的 traces 做聚合。 比如, p99 延迟的请求有个标签是 customer_type='premium'。 而这些在 SigNoz 可以轻松做到。
<p>&nbsp </p>
@@ -185,7 +185,7 @@ Jaeger 仅仅是一个分布式追踪系统。 但是 SigNoz 可以提供 metric
我们 ❤️ 你的贡献,无论大小。 请先阅读 [CONTRIBUTING.md](CONTRIBUTING.md) 再开始给 SigNoz 做贡献。
如果你不知道如何开始? 只需要在 [slack 社区](https://signoz.io/slack) 通过 `#contributing` 频道联系我们。
如果你不知道如何开始? 只需要在 [slack 社区](https://signoz.io/slack) 通过 `#contributing` 频道联系我们。
### 项目维护人员
@@ -199,6 +199,8 @@ Jaeger 仅仅是一个分布式追踪系统。 但是 SigNoz 可以提供 metric
#### 前端
- [Palash Gupta](https://github.com/palashgdev)
- [Yunus M](https://github.com/YounixM)
- [Rajat Dabade](https://github.com/Rajat-Dabade)
#### 运维开发

View File

@@ -1,7 +1,7 @@
version: "3.9"
x-clickhouse-defaults: &clickhouse-defaults
image: clickhouse/clickhouse-server:23.7.3-alpine
image: clickhouse/clickhouse-server:23.11.1-alpine
tty: true
deploy:
restart_policy:
@@ -146,7 +146,7 @@ services:
condition: on-failure
query-service:
image: signoz/query-service:0.32.1
image: signoz/query-service:0.36.2
command:
[
"-config=/root/config/prometheus.yml",
@@ -186,7 +186,7 @@ services:
<<: *db-depend
frontend:
image: signoz/frontend:0.32.1
image: signoz/frontend:0.36.2
deploy:
restart_policy:
condition: on-failure
@@ -199,7 +199,7 @@ services:
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
otel-collector:
image: signoz/signoz-otel-collector:0.79.12
image: signoz/signoz-otel-collector:0.88.6
command:
[
"--config=/etc/otel-collector-config.yaml",
@@ -237,7 +237,7 @@ services:
- query-service
otel-collector-migrator:
image: signoz/signoz-schema-migrator:0.79.12
image: signoz/signoz-schema-migrator:0.88.6
deploy:
restart_policy:
condition: on-failure
@@ -250,7 +250,7 @@ services:
# - clickhouse-3
otel-collector-metrics:
image: signoz/signoz-otel-collector:0.79.12
image: signoz/signoz-otel-collector:0.88.6
command:
[
"--config=/etc/otel-collector-metrics-config.yaml",

View File

@@ -61,40 +61,6 @@ receivers:
job_name: otel-collector
processors:
logstransform/internal:
operators:
- type: trace_parser
if: '"trace_id" in attributes or "span_id" in attributes'
trace_id:
parse_from: attributes.trace_id
span_id:
parse_from: attributes.span_id
output: remove_trace_id
- type: trace_parser
if: '"traceId" in attributes or "spanId" in attributes'
trace_id:
parse_from: attributes.traceId
span_id:
parse_from: attributes.spanId
output: remove_traceId
- id: remove_traceId
type: remove
if: '"traceId" in attributes'
field: attributes.traceId
output: remove_spanId
- id: remove_spanId
type: remove
if: '"spanId" in attributes'
field: attributes.spanId
- id: remove_trace_id
type: remove
if: '"trace_id" in attributes'
field: attributes.trace_id
output: remove_span_id
- id: remove_span_id
type: remove
if: '"span_id" in attributes'
field: attributes.span_id
batch:
send_batch_size: 10000
send_batch_max_size: 11000
@@ -193,5 +159,5 @@ service:
exporters: [prometheus]
logs:
receivers: [otlp, tcplog/docker]
processors: [logstransform/internal, batch]
processors: [batch]
exporters: [clickhouselogsexporter]

View File

@@ -66,7 +66,7 @@ services:
- --storage.path=/data
otel-collector-migrator:
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.79.12}
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.6}
container_name: otel-migrator
command:
- "--dsn=tcp://clickhouse:9000"
@@ -81,7 +81,7 @@ services:
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
otel-collector:
container_name: signoz-otel-collector
image: signoz/signoz-otel-collector:0.79.12
image: signoz/signoz-otel-collector:0.88.6
command:
[
"--config=/etc/otel-collector-config.yaml",
@@ -118,7 +118,7 @@ services:
otel-collector-metrics:
container_name: signoz-otel-collector-metrics
image: signoz/signoz-otel-collector:0.79.12
image: signoz/signoz-otel-collector:0.88.6
command:
[
"--config=/etc/otel-collector-metrics-config.yaml",

View File

@@ -3,7 +3,7 @@ version: "2.4"
x-clickhouse-defaults: &clickhouse-defaults
restart: on-failure
# addding non LTS version due to this fix https://github.com/ClickHouse/ClickHouse/commit/32caf8716352f45c1b617274c7508c86b7d1afab
image: clickhouse/clickhouse-server:23.7.3-alpine
image: clickhouse/clickhouse-server:23.11.1-alpine
tty: true
depends_on:
- zookeeper-1
@@ -164,7 +164,7 @@ services:
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
query-service:
image: signoz/query-service:${DOCKER_TAG:-0.32.1}
image: signoz/query-service:${DOCKER_TAG:-0.36.2}
container_name: signoz-query-service
command:
[
@@ -203,7 +203,7 @@ services:
<<: *db-depend
frontend:
image: signoz/frontend:${DOCKER_TAG:-0.32.1}
image: signoz/frontend:${DOCKER_TAG:-0.36.2}
container_name: signoz-frontend
restart: on-failure
depends_on:
@@ -215,7 +215,7 @@ services:
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
otel-collector-migrator:
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.79.12}
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.6}
container_name: otel-migrator
command:
- "--dsn=tcp://clickhouse:9000"
@@ -229,7 +229,7 @@ services:
otel-collector:
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.79.12}
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.88.6}
container_name: signoz-otel-collector
command:
[
@@ -269,7 +269,7 @@ services:
condition: service_healthy
otel-collector-metrics:
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.79.12}
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.88.6}
container_name: signoz-otel-collector-metrics
command:
[

View File

@@ -62,40 +62,6 @@ receivers:
processors:
logstransform/internal:
operators:
- type: trace_parser
if: '"trace_id" in attributes or "span_id" in attributes'
trace_id:
parse_from: attributes.trace_id
span_id:
parse_from: attributes.span_id
output: remove_trace_id
- type: trace_parser
if: '"traceId" in attributes or "spanId" in attributes'
trace_id:
parse_from: attributes.traceId
span_id:
parse_from: attributes.spanId
output: remove_traceId
- id: remove_traceId
type: remove
if: '"traceId" in attributes'
field: attributes.traceId
output: remove_spanId
- id: remove_spanId
type: remove
if: '"spanId" in attributes'
field: attributes.spanId
- id: remove_trace_id
type: remove
if: '"trace_id" in attributes'
field: attributes.trace_id
output: remove_span_id
- id: remove_span_id
type: remove
if: '"span_id" in attributes'
field: attributes.span_id
batch:
send_batch_size: 10000
send_batch_max_size: 11000
@@ -198,5 +164,5 @@ service:
exporters: [prometheus]
logs:
receivers: [otlp, tcplog/docker]
processors: [logstransform/internal, batch]
processors: [batch]
exporters: [clickhouselogsexporter]

14
e2e/package.json Normal file
View File

@@ -0,0 +1,14 @@
{
"name": "e2e",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@playwright/test": "^1.22.0",
"@types/node": "^20.9.2"
},
"scripts": {},
"dependencies": {
"dotenv": "8.2.0"
}
}

46
e2e/playwright.config.ts Normal file
View File

@@ -0,0 +1,46 @@
import { defineConfig, devices } from "@playwright/test";
import dotenv from "dotenv";
dotenv.config();
export default defineConfig({
testDir: "./tests",
fullyParallel: true,
forbidOnly: !!process.env.CI,
name: "Signoz E2E",
retries: process.env.CI ? 2 : 0,
reporter: process.env.CI ? "github" : "list",
preserveOutput: "always",
updateSnapshots: "all",
quiet: false,
testMatch: ["**/*.spec.ts"],
use: {
trace: "on-first-retry",
baseURL:
process.env.PLAYWRIGHT_TEST_BASE_URL || "https://stagingapp.signoz.io/",
},
projects: [
{ name: "setup", testMatch: /.*\.setup\.ts/ },
{
name: "chromium",
use: {
...devices["Desktop Chrome"],
// Use prepared auth state.
storageState: ".auth/user.json",
},
dependencies: ["setup"],
},
],
});

37
e2e/tests/auth.setup.ts Normal file
View File

@@ -0,0 +1,37 @@
import { test, expect } from "@playwright/test";
import ROUTES from "../../frontend/src/constants/routes";
import dotenv from "dotenv";
dotenv.config();
const authFile = ".auth/user.json";
test("E2E Login Test", async ({ page }) => {
await Promise.all([page.goto("/"), page.waitForRequest("**/version")]);
const signup = "Monitor your applications. Find what is causing issues.";
const el = await page.locator(`text=${signup}`);
expect(el).toBeVisible();
await page
.locator("id=loginEmail")
.type(
process.env.PLAYWRIGHT_USERNAME ? process.env.PLAYWRIGHT_USERNAME : ""
);
await page.getByText("Next").click();
await page
.locator('input[id="currentPassword"]')
.fill(
process.env.PLAYWRIGHT_PASSWORD ? process.env.PLAYWRIGHT_PASSWORD : ""
);
await page.locator('button[data-attr="signup"]').click();
await expect(page).toHaveURL(ROUTES.APPLICATION);
await page.context().storageState({ path: authFile });
});

10
e2e/tests/contants.ts Normal file
View File

@@ -0,0 +1,10 @@
export const SERVICE_TABLE_HEADERS = {
APPLICATION: "Applicaton",
P99LATENCY: "P99 latency (in ms)",
ERROR_RATE: "Error Rate (% of total)",
OPS_PER_SECOND: "Operations Per Second",
};
export const DATA_TEST_IDS = {
NEW_DASHBOARD_BTN: "create-new-dashboard",
};

View File

@@ -0,0 +1,40 @@
import { test, expect } from "@playwright/test";
import ROUTES from "../../frontend/src/constants/routes";
import { DATA_TEST_IDS, SERVICE_TABLE_HEADERS } from "./contants";
test("Basic Navigation Check across different resources", async ({ page }) => {
// route to services page and check if the page renders fine with BE contract
await Promise.all([
page.goto(ROUTES.APPLICATION),
page.waitForRequest("**/v1/services"),
]);
const p99Latency = page.locator(
`th:has-text("${SERVICE_TABLE_HEADERS.P99LATENCY}")`
);
await expect(p99Latency).toBeVisible();
// route to the new trace explorer page and check if the page renders fine
await page.goto(ROUTES.TRACES_EXPLORER);
await page.waitForLoadState("networkidle");
const listViewTable = await page
.locator('div[role="presentation"]')
.isVisible();
expect(listViewTable).toBeTruthy();
// route to the dashboards page and check if the page renders fine
await Promise.all([
page.goto(ROUTES.ALL_DASHBOARD),
page.waitForRequest("**/v1/dashboards"),
]);
const newDashboardBtn = await page
.locator(`data-testid=${DATA_TEST_IDS.NEW_DASHBOARD_BTN}`)
.isVisible();
expect(newDashboardBtn).toBeTruthy();
});

46
e2e/yarn.lock Normal file
View File

@@ -0,0 +1,46 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@playwright/test@^1.22.0":
version "1.40.0"
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.40.0.tgz#d06c506977dd7863aa16e07f2136351ecc1be6ed"
integrity sha512-PdW+kn4eV99iP5gxWNSDQCbhMaDVej+RXL5xr6t04nbKLCBwYtA046t7ofoczHOm8u6c+45hpDKQVZqtqwkeQg==
dependencies:
playwright "1.40.0"
"@types/node@^20.9.2":
version "20.9.2"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.2.tgz#002815c8e87fe0c9369121c78b52e800fadc0ac6"
integrity sha512-WHZXKFCEyIUJzAwh3NyyTHYSR35SevJ6mZ1nWwJafKtiQbqRTIKSRcw3Ma3acqgsent3RRDqeVwpHntMk+9irg==
dependencies:
undici-types "~5.26.4"
dotenv@8.2.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
fsevents@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
playwright-core@1.40.0:
version "1.40.0"
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.40.0.tgz#82f61e5504cb3097803b6f8bbd98190dd34bdf14"
integrity sha512-fvKewVJpGeca8t0ipM56jkVSU6Eo0RmFvQ/MaCQNDYm+sdvKkMBBWTE1FdeMqIdumRaXXjZChWHvIzCGM/tA/Q==
playwright@1.40.0:
version "1.40.0"
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.40.0.tgz#2a1824b9fe5c4fe52ed53db9ea68003543a99df0"
integrity sha512-gyHAgQjiDf1m34Xpwzaqb76KgfzYrhK7iih+2IzcOCoZWr/8ZqmdBw+t0RU85ZmfJMgtgAiNtBQ/KS2325INXw==
dependencies:
playwright-core "1.40.0"
optionalDependencies:
fsevents "2.3.2"
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==

View File

@@ -1,5 +1,5 @@
# use a minimal alpine image
FROM alpine:3.17
FROM alpine:3.18.5
# Add Maintainer Info
LABEL maintainer="signoz"
@@ -18,6 +18,7 @@ COPY ee/query-service/bin/query-service-${TARGETOS}-${TARGETARCH} /root/query-se
# copy prometheus YAML config
COPY pkg/query-service/config/prometheus.yml /root/config/prometheus.yml
COPY pkg/query-service/templates /root/templates
# Make query-service executable for non-root users
RUN chmod 755 /root /root/query-service

View File

@@ -150,6 +150,7 @@ func (ah *APIHandler) RegisterRoutes(router *mux.Router, am *baseapp.AuthMiddlew
router.HandleFunc("/api/v1/login", am.OpenAccess(ah.loginUser)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/traces/{traceId}", am.ViewAccess(ah.searchTraces)).Methods(http.MethodGet)
router.HandleFunc("/api/v2/metrics/query_range", am.ViewAccess(ah.queryRangeMetricsV2)).Methods(http.MethodPost)
router.HandleFunc("/api/v3/query_range", am.ViewAccess(ah.QueryRangeV3)).Methods(http.MethodPost)
// PAT APIs
router.HandleFunc("/api/v1/pat", am.OpenAccess(ah.createPAT)).Methods(http.MethodPost)
@@ -160,6 +161,13 @@ func (ah *APIHandler) RegisterRoutes(router *mux.Router, am *baseapp.AuthMiddlew
router.HandleFunc("/api/v1/billing", am.AdminAccess(ah.getBilling)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/portal", am.AdminAccess(ah.portalSession)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/dashboards/{uuid}/lock", am.EditAccess(ah.lockDashboard)).Methods(http.MethodPut)
router.HandleFunc("/api/v1/dashboards/{uuid}/unlock", am.EditAccess(ah.unlockDashboard)).Methods(http.MethodPut)
router.HandleFunc("/api/v1/limits", am.AdminAccess(ah.getQueryLimits)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/limits", am.AdminAccess(ah.addQueryLimits)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/limits", am.AdminAccess(ah.updateQueryLimits)).Methods(http.MethodPut)
router.HandleFunc("/api/v2/licenses",
am.ViewAccess(ah.listLicensesV2)).
Methods(http.MethodGet)

View File

@@ -0,0 +1,51 @@
package api
import (
"github.com/gorilla/mux"
"go.signoz.io/signoz/pkg/query-service/app/dashboards"
"go.signoz.io/signoz/pkg/query-service/auth"
"go.signoz.io/signoz/pkg/query-service/common"
"go.signoz.io/signoz/pkg/query-service/model"
"net/http"
)
func (ah *APIHandler) lockDashboard(w http.ResponseWriter, r *http.Request) {
ah.lockUnlockDashboard(w, r, true)
}
func (ah *APIHandler) unlockDashboard(w http.ResponseWriter, r *http.Request) {
ah.lockUnlockDashboard(w, r, false)
}
func (ah *APIHandler) lockUnlockDashboard(w http.ResponseWriter, r *http.Request, lock bool) {
// Locking can only be done by the owner of the dashboard
// or an admin
// - Fetch the dashboard
// - Check if the user is the owner or an admin
// - If yes, lock/unlock the dashboard
// - If no, return 403
// Get the dashboard UUID from the request
uuid := mux.Vars(r)["uuid"]
dashboard, err := dashboards.GetDashboard(r.Context(), uuid)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, err.Error())
return
}
user := common.GetUserFromContext(r.Context())
if !auth.IsAdmin(user) && (dashboard.CreateBy != nil && *dashboard.CreateBy != user.Email) {
RespondError(w, &model.ApiError{Typ: model.ErrorForbidden, Err: err}, "You are not authorized to lock/unlock this dashboard")
return
}
// Lock/Unlock the dashboard
err = dashboards.LockUnlockDashboard(r.Context(), uuid, lock)
if err != nil {
RespondError(w, &model.ApiError{Typ: model.ErrorInternal, Err: err}, err.Error())
return
}
ah.Respond(w, "Dashboard updated successfully")
}

View File

@@ -52,7 +52,6 @@ func (ah *APIHandler) listLicenses(w http.ResponseWriter, r *http.Request) {
}
func (ah *APIHandler) applyLicense(w http.ResponseWriter, r *http.Request) {
ctx := context.Background()
var l model.License
if err := json.NewDecoder(r.Body).Decode(&l); err != nil {
@@ -64,8 +63,7 @@ func (ah *APIHandler) applyLicense(w http.ResponseWriter, r *http.Request) {
RespondError(w, model.BadRequest(fmt.Errorf("license key is required")), nil)
return
}
license, apiError := ah.LM().Activate(ctx, l.Key)
license, apiError := ah.LM().Activate(r.Context(), l.Key)
if apiError != nil {
RespondError(w, apiError, nil)
return

View File

@@ -0,0 +1,51 @@
package api
import (
"encoding/json"
"net/http"
"go.signoz.io/signoz/ee/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
)
func (aH *APIHandler) getQueryLimits(w http.ResponseWriter, r *http.Request) {
queryLimits, err := aH.AppDao().GetQueryLimits(r.Context())
if err != nil {
RespondError(w, &basemodel.ApiError{Typ: basemodel.ErrorInternal, Err: err}, nil)
return
}
aH.Respond(w, queryLimits)
}
func (aH *APIHandler) addQueryLimits(w http.ResponseWriter, r *http.Request) {
var queryLimits []*model.QueryLimit
if err := json.NewDecoder(r.Body).Decode(&queryLimits); err != nil {
RespondError(w, &basemodel.ApiError{Typ: basemodel.ErrorBadData, Err: err}, nil)
return
}
err := aH.AppDao().AddQueryLimits(r.Context(), queryLimits)
if err != nil {
RespondError(w, &basemodel.ApiError{Typ: basemodel.ErrorInternal, Err: err}, nil)
return
}
aH.Respond(w, nil)
}
func (aH *APIHandler) updateQueryLimits(w http.ResponseWriter, r *http.Request) {
var queryLimits []*model.QueryLimit
if err := json.NewDecoder(r.Body).Decode(&queryLimits); err != nil {
RespondError(w, &basemodel.ApiError{Typ: basemodel.ErrorBadData, Err: err}, nil)
return
}
err := aH.AppDao().UpdateQueryLimits(r.Context(), queryLimits)
if err != nil {
RespondError(w, &basemodel.ApiError{Typ: basemodel.ErrorInternal, Err: err}, nil)
return
}
aH.Respond(w, nil)
}

View File

@@ -4,14 +4,17 @@ import (
"bytes"
"fmt"
"net/http"
"strings"
"sync"
"text/template"
"time"
"go.signoz.io/signoz/pkg/query-service/app"
"go.signoz.io/signoz/pkg/query-service/app/metrics"
"go.signoz.io/signoz/pkg/query-service/app/parser"
"go.signoz.io/signoz/pkg/query-service/constants"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
querytemplate "go.signoz.io/signoz/pkg/query-service/utils/queryTemplate"
"go.uber.org/zap"
)
@@ -234,3 +237,52 @@ func (ah *APIHandler) queryRangeMetricsV2(w http.ResponseWriter, r *http.Request
resp := ResponseFormat{ResultType: "matrix", Result: seriesList, TableName: tableName}
ah.Respond(w, resp)
}
func (aH *APIHandler) QueryRangeV3(w http.ResponseWriter, r *http.Request) {
queryRangeParams, apiErrorObj := app.ParseQueryRangeParams(r)
if apiErrorObj != nil {
zap.S().Errorf(apiErrorObj.Err.Error())
RespondError(w, apiErrorObj, nil)
return
}
limits, err := aH.AppDao().GetQueryLimits(r.Context())
if err != nil {
zap.S().Errorf("Error while getting query limits: %v", err)
// We don't want to fail the request if we can't get the limits
// iterate over the nil slice will not execute the loop
// and the query will be executed without any limits
// this shouldn't happen ideally but we don't want to fail the request
}
var timeSeriesLimt int
for _, limit := range limits {
if limit.Name == "time_series_limit" {
timeSeriesLimt = limit.UsageLimit
}
}
if len(queryRangeParams.CompositeQuery.BuilderQueries) > 0 {
for idx := range queryRangeParams.CompositeQuery.BuilderQueries {
queryRangeParams.CompositeQuery.BuilderQueries[idx].QueryLimits = v3.QueryLimits{
MaxTimeSeries: timeSeriesLimt,
}
// TODO(srikanthccv): should apply to explore page also
if !strings.Contains(queryRangeParams.SourcePage, "dashboard") {
queryRangeParams.CompositeQuery.BuilderQueries[idx].QueryLimits.MaxTimeSeries = 0
}
}
}
// add temporality for each metric
temporalityErr := aH.APIHandler.AddTemporality(r.Context(), queryRangeParams)
if temporalityErr != nil {
zap.S().Errorf("Error while adding temporality for metrics: %v", temporalityErr)
RespondError(w, &basemodel.ApiError{Typ: basemodel.ErrorInternal, Err: temporalityErr}, nil)
return
}
aH.APIHandler.ExecQueryRangeV3(r.Context(), queryRangeParams, w, r)
}

View File

@@ -12,6 +12,7 @@ import (
"github.com/gorilla/mux"
"go.signoz.io/signoz/ee/query-service/model"
"go.signoz.io/signoz/pkg/query-service/auth"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.uber.org/zap"
)
@@ -47,8 +48,18 @@ func (ah *APIHandler) createPAT(w http.ResponseWriter, r *http.Request) {
req.CreatedAt = time.Now().Unix()
req.Token = generatePATToken()
// default expiry is 30 days
if req.ExpiresAt == 0 {
req.ExpiresAt = time.Now().AddDate(0, 0, 30).Unix()
}
// max expiry is 1 year
if req.ExpiresAt > time.Now().AddDate(1, 0, 0).Unix() {
req.ExpiresAt = time.Now().AddDate(1, 0, 0).Unix()
}
zap.S().Debugf("Got PAT request: %+v", req)
if apierr := ah.AppDao().CreatePAT(ctx, &req); apierr != nil {
var apierr basemodel.BaseApiError
if req, apierr = ah.AppDao().CreatePAT(ctx, req); apierr != nil {
RespondError(w, apierr, nil)
return
}

View File

@@ -23,6 +23,7 @@ import (
"go.signoz.io/signoz/ee/query-service/constants"
"go.signoz.io/signoz/ee/query-service/dao"
"go.signoz.io/signoz/ee/query-service/interfaces"
"go.signoz.io/signoz/pkg/query-service/auth"
baseInterface "go.signoz.io/signoz/pkg/query-service/interfaces"
v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
@@ -41,7 +42,6 @@ import (
baseconst "go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/healthcheck"
basealm "go.signoz.io/signoz/pkg/query-service/integrations/alertManager"
baseint "go.signoz.io/signoz/pkg/query-service/interfaces"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
pqle "go.signoz.io/signoz/pkg/query-service/pqlEngine"
rules "go.signoz.io/signoz/pkg/query-service/rules"
@@ -86,7 +86,7 @@ type Server struct {
privateHTTP *http.Server
// feature flags
featureLookup baseint.FeatureLookup
featureLookup baseInterface.FeatureLookup
// Usage manager
usageManager *usage.Manager
@@ -437,7 +437,10 @@ func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface
telemetry.GetInstance().AddActiveLogsUser()
}
data["dataSources"] = dataSources
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_QUERY_RANGE_V3, data, true)
userEmail, err := auth.GetEmailFromJwt(r.Context())
if err == nil {
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_QUERY_RANGE_V3, data, userEmail, true)
}
}
return data, true
}
@@ -458,6 +461,8 @@ func getActiveLogs(path string, r *http.Request) {
func (s *Server) analyticsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := auth.AttachJwtToContext(r.Context(), r)
r = r.WithContext(ctx)
route := mux.CurrentRoute(r)
path, _ := route.GetPathTemplate()
@@ -474,8 +479,11 @@ func (s *Server) analyticsMiddleware(next http.Handler) http.Handler {
}
}
if _, ok := telemetry.IgnoredPaths()[path]; !ok {
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_PATH, data)
if _, ok := telemetry.EnabledPaths()[path]; ok {
userEmail, err := auth.GetEmailFromJwt(r.Context())
if err == nil {
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_PATH, data, userEmail)
}
}
})
@@ -632,7 +640,7 @@ func makeRulesManager(
alertManagerURL string,
ruleRepoURL string,
db *sqlx.DB,
ch baseint.Reader,
ch baseInterface.Reader,
disableRules bool,
fm baseInterface.FeatureLookup) (*rules.Manager, error) {

View File

@@ -33,10 +33,14 @@ type ModelDao interface {
DeleteDomain(ctx context.Context, id uuid.UUID) basemodel.BaseApiError
GetDomainByEmail(ctx context.Context, email string) (*model.OrgDomain, basemodel.BaseApiError)
CreatePAT(ctx context.Context, p *model.PAT) basemodel.BaseApiError
CreatePAT(ctx context.Context, p model.PAT) (model.PAT, basemodel.BaseApiError)
GetPAT(ctx context.Context, pat string) (*model.PAT, basemodel.BaseApiError)
GetPATByID(ctx context.Context, id string) (*model.PAT, basemodel.BaseApiError)
GetUserByPAT(ctx context.Context, token string) (*basemodel.UserPayload, basemodel.BaseApiError)
ListPATs(ctx context.Context, userID string) ([]model.PAT, basemodel.BaseApiError)
DeletePAT(ctx context.Context, id string) basemodel.BaseApiError
GetQueryLimits(ctx context.Context) ([]*model.QueryLimit, error)
AddQueryLimits(ctx context.Context, queryLimits []*model.QueryLimit) error
UpdateQueryLimits(ctx context.Context, queryLimits []*model.QueryLimit) error
}

View File

@@ -0,0 +1,54 @@
package sqlite
import (
"context"
"go.signoz.io/signoz/ee/query-service/model"
)
// GetQueryLimits returns the query limits
func (m *modelDao) GetQueryLimits(ctx context.Context) ([]*model.QueryLimit, error) {
query := `SELECT name, title, usage_limit FROM resource_usage_limits`
var queryLimits []*model.QueryLimit
err := m.DB().Select(&queryLimits, query)
if err != nil {
return nil, err
}
return queryLimits, nil
}
// AddQueryLimits adds the query limits
func (m *modelDao) AddQueryLimits(ctx context.Context, queryLimits []*model.QueryLimit) error {
tx := m.DB().MustBegin()
for _, queryLimit := range queryLimits {
query := `INSERT INTO resource_usage_limits (name, title, usage_limit) VALUES (?, ?, ?)`
_, err := tx.Exec(query, queryLimit.Name, queryLimit.Title, queryLimit.UsageLimit)
if err != nil {
tx.Rollback()
return err
}
}
err := tx.Commit()
if err != nil {
return err
}
return nil
}
// UpdateQueryLimits updates the query limits
func (m *modelDao) UpdateQueryLimits(ctx context.Context, queryLimits []*model.QueryLimit) error {
tx := m.DB().MustBegin()
for _, queryLimit := range queryLimits {
query := `UPDATE resource_usage_limits SET usage_limit = ? WHERE name = ?`
_, err := tx.Exec(query, queryLimit.UsageLimit, queryLimit.Name)
if err != nil {
tx.Rollback()
return err
}
}
err := tx.Commit()
if err != nil {
return err
}
return nil
}

View File

@@ -38,7 +38,7 @@ func InitDB(dataSourceName string) (*modelDao, error) {
basedao.SetDB(dao)
m := &modelDao{ModelDaoSqlite: dao}
table_schema := `
tableSchema := `
PRAGMA foreign_keys = ON;
CREATE TABLE IF NOT EXISTS org_domains(
id TEXT PRIMARY KEY,
@@ -60,11 +60,23 @@ func InitDB(dataSourceName string) (*modelDao, error) {
);
`
_, err = m.DB().Exec(table_schema)
_, err = m.DB().Exec(tableSchema)
if err != nil {
return nil, fmt.Errorf("error in creating tables: %v", err.Error())
}
// create resource_usage_limits table
tableSchema = `CREATE TABLE IF NOT EXISTS resource_usage_limits (
name TEXT PRIMARY KEY,
title TEXT,
usage_limit INTEGER DEFAULT 0
);`
_, err = m.DB().Exec(tableSchema)
if err != nil {
return nil, fmt.Errorf("Error in creating resource_usage_limits table: %s", err.Error())
}
return m, nil
}

View File

@@ -3,14 +3,15 @@ package sqlite
import (
"context"
"fmt"
"strconv"
"go.signoz.io/signoz/ee/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.uber.org/zap"
)
func (m *modelDao) CreatePAT(ctx context.Context, p *model.PAT) basemodel.BaseApiError {
_, err := m.DB().ExecContext(ctx,
func (m *modelDao) CreatePAT(ctx context.Context, p model.PAT) (model.PAT, basemodel.BaseApiError) {
result, err := m.DB().ExecContext(ctx,
"INSERT INTO personal_access_tokens (user_id, token, name, created_at, expires_at) VALUES ($1, $2, $3, $4, $5)",
p.UserID,
p.Token,
@@ -19,9 +20,15 @@ func (m *modelDao) CreatePAT(ctx context.Context, p *model.PAT) basemodel.BaseAp
p.ExpiresAt)
if err != nil {
zap.S().Errorf("Failed to insert PAT in db, err: %v", zap.Error(err))
return model.InternalError(fmt.Errorf("PAT insertion failed"))
return model.PAT{}, model.InternalError(fmt.Errorf("PAT insertion failed"))
}
return nil
id, err := result.LastInsertId()
if err != nil {
zap.S().Errorf("Failed to get last inserted id, err: %v", zap.Error(err))
return model.PAT{}, model.InternalError(fmt.Errorf("PAT insertion failed"))
}
p.Id = strconv.Itoa(int(id))
return p, nil
}
func (m *modelDao) ListPATs(ctx context.Context, userID string) ([]model.PAT, basemodel.BaseApiError) {
@@ -90,7 +97,7 @@ func (m *modelDao) GetUserByPAT(ctx context.Context, token string) (*basemodel.U
u.org_id,
u.group_id
FROM users u, personal_access_tokens p
WHERE u.id = p.user_id and p.token=?;`
WHERE u.id = p.user_id and p.token=? and p.expires_at >= strftime('%s', 'now');`
if err := m.DB().Select(&users, query, token); err != nil {
return nil, model.InternalError(fmt.Errorf("failed to fetch user from PAT, err: %v", err))

View File

@@ -10,6 +10,7 @@ import (
"sync"
"go.signoz.io/signoz/pkg/query-service/auth"
baseconstants "go.signoz.io/signoz/pkg/query-service/constants"
validate "go.signoz.io/signoz/ee/query-service/integrations/signozio"
@@ -203,7 +204,7 @@ func (lm *Manager) Validate(ctx context.Context) (reterr error) {
zap.S().Errorf("License validation completed with error", reterr)
atomic.AddUint64(&lm.failedAttempts, 1)
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_LICENSE_CHECK_FAILED,
map[string]interface{}{"err": reterr.Error()})
map[string]interface{}{"err": reterr.Error()}, "")
} else {
zap.S().Info("License validation completed with no errors")
}
@@ -259,8 +260,11 @@ func (lm *Manager) Validate(ctx context.Context) (reterr error) {
func (lm *Manager) Activate(ctx context.Context, key string) (licenseResponse *model.License, errResponse *model.ApiError) {
defer func() {
if errResponse != nil {
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_LICENSE_ACT_FAILED,
map[string]interface{}{"err": errResponse.Err.Error()})
userEmail, err := auth.GetEmailFromJwt(ctx)
if err == nil {
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_LICENSE_ACT_FAILED,
map[string]interface{}{"err": errResponse.Err.Error()}, userEmail)
}
}
}()

View File

@@ -9,8 +9,8 @@ import (
"github.com/google/uuid"
"github.com/pkg/errors"
saml2 "github.com/russellhaering/gosaml2"
"go.signoz.io/signoz/ee/query-service/sso/saml"
"go.signoz.io/signoz/ee/query-service/sso"
"go.signoz.io/signoz/ee/query-service/sso/saml"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.uber.org/zap"
)
@@ -24,16 +24,16 @@ const (
// OrgDomain identify org owned web domains for auth and other purposes
type OrgDomain struct {
Id uuid.UUID `json:"id"`
Name string `json:"name"`
OrgId string `json:"orgId"`
SsoEnabled bool `json:"ssoEnabled"`
SsoType SSOType `json:"ssoType"`
Id uuid.UUID `json:"id"`
Name string `json:"name"`
OrgId string `json:"orgId"`
SsoEnabled bool `json:"ssoEnabled"`
SsoType SSOType `json:"ssoType"`
SamlConfig *SamlConfig `json:"samlConfig"`
SamlConfig *SamlConfig `json:"samlConfig"`
GoogleAuthConfig *GoogleOAuthConfig `json:"googleAuthConfig"`
Org *basemodel.Organization
Org *basemodel.Organization
}
func (od *OrgDomain) String() string {
@@ -100,8 +100,8 @@ func (od *OrgDomain) GetSAMLCert() string {
return ""
}
// PrepareGoogleOAuthProvider creates GoogleProvider that is used in
// requesting OAuth and also used in processing response from google
// PrepareGoogleOAuthProvider creates GoogleProvider that is used in
// requesting OAuth and also used in processing response from google
func (od *OrgDomain) PrepareGoogleOAuthProvider(siteUrl *url.URL) (sso.OAuthCallbackProvider, error) {
if od.GoogleAuthConfig == nil {
return nil, fmt.Errorf("Google auth is not setup correctly for this domain")
@@ -137,38 +137,36 @@ func (od *OrgDomain) PrepareSamlRequest(siteUrl *url.URL) (*saml2.SAMLServicePro
}
func (od *OrgDomain) BuildSsoUrl(siteUrl *url.URL) (ssoUrl string, err error) {
fmtDomainId := strings.Replace(od.Id.String(), "-", ":", -1)
// build redirect url from window.location sent by frontend
redirectURL := fmt.Sprintf("%s://%s%s", siteUrl.Scheme, siteUrl.Host, siteUrl.Path)
// prepare state that gets relayed back when the auth provider
// calls back our url. here we pass the app url (where signoz runs)
// and the domain Id. The domain Id helps in identifying sso config
// when the call back occurs and the app url is useful in redirecting user
// back to the right path.
// when the call back occurs and the app url is useful in redirecting user
// back to the right path.
// why do we need to pass app url? the callback typically is handled by backend
// and sometimes backend might right at a different port or is unaware of frontend
// endpoint (unless SITE_URL param is set). hence, we receive this build sso request
// along with frontend window.location and use it to relay the information through
// auth provider to the backend (HandleCallback or HandleSSO method).
// along with frontend window.location and use it to relay the information through
// auth provider to the backend (HandleCallback or HandleSSO method).
relayState := fmt.Sprintf("%s?domainId=%s", redirectURL, fmtDomainId)
switch (od.SsoType) {
switch od.SsoType {
case SAML:
sp, err := od.PrepareSamlRequest(siteUrl)
if err != nil {
return "", err
}
return sp.BuildAuthURL(relayState)
case GoogleAuth:
googleProvider, err := od.PrepareGoogleOAuthProvider(siteUrl)
if err != nil {
return "", err
@@ -177,8 +175,7 @@ func (od *OrgDomain) BuildSsoUrl(siteUrl *url.URL) (ssoUrl string, err error) {
default:
zap.S().Errorf("found unsupported SSO config for the org domain", zap.String("orgDomain", od.Name))
return "", fmt.Errorf("unsupported SSO config for the domain")
return "", fmt.Errorf("unsupported SSO config for the domain")
}
}

View File

@@ -0,0 +1,12 @@
package model
type QueryLimit struct {
// Name of the query limit
Name string `db:"name" json:"name"`
// Title of the query limit
Title string `db:"title" json:"title"`
// UsageLimit indicates the usage limit of the query
// If the usage limit is 0, then there is no limit
UsageLimit int `db:"usage_limit" json:"usage_limit"`
}

View File

@@ -6,5 +6,5 @@ type PAT struct {
Token string `json:"token" db:"token"`
Name string `json:"name" db:"name"`
CreatedAt int64 `json:"createdAt" db:"created_at"`
ExpiresAt int64 `json:"expiresAt" db:"expires_at"` // unused as of now
ExpiresAt int64 `json:"expiresAt" db:"expires_at"`
}

View File

@@ -52,14 +52,14 @@ var BasicPlan = basemodel.FeatureSet{
Name: basemodel.QueryBuilderPanels,
Active: true,
Usage: 0,
UsageLimit: 5,
UsageLimit: 20,
Route: "",
},
basemodel.Feature{
Name: basemodel.QueryBuilderAlerts,
Active: true,
Usage: 0,
UsageLimit: 5,
UsageLimit: 10,
Route: "",
},
basemodel.Feature{

View File

@@ -86,6 +86,7 @@ module.exports = {
},
],
'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
'no-plusplus': 'off',
'jsx-a11y/label-has-associated-control': [
'error',
{
@@ -109,7 +110,6 @@ module.exports = {
// eslint rules need to remove
'@typescript-eslint/no-shadow': 'off',
'import/no-cycle': 'off',
'prettier/prettier': [
'error',
{},

View File

@@ -2,3 +2,19 @@
. "$(dirname "$0")/_/husky.sh"
cd frontend && yarn run commitlint --edit $1
branch="$(git rev-parse --abbrev-ref HEAD)"
color_red="$(tput setaf 1)"
bold="$(tput bold)"
reset="$(tput sgr0)"
if [ "$branch" = "main" ]; then
echo "${color_red}${bold}You can't commit directly to the main branch${reset}"
exit 1
fi
if [ "$branch" = "develop" ]; then
echo "${color_red}${bold}You can't commit directly to the develop branch${reset}"
exit 1
fi

View File

@@ -22,7 +22,7 @@ const config: Config.InitialOptions = {
'^.+\\.(js|jsx)$': 'babel-jest',
},
transformIgnorePatterns: [
'node_modules/(?!(lodash-es|react-dnd|core-dnd|@react-dnd|dnd-core|react-dnd-html5-backend)/)',
'node_modules/(?!(lodash-es|react-dnd|core-dnd|@react-dnd|dnd-core|react-dnd-html5-backend|axios)/)',
],
setupFilesAfterEnv: ['<rootDir>jest.setup.ts'],
testPathIgnorePatterns: ['/node_modules/', '/public/'],

View File

@@ -29,6 +29,9 @@
"dependencies": {
"@ant-design/colors": "6.0.0",
"@ant-design/icons": "4.8.0",
"@dnd-kit/core": "6.1.0",
"@dnd-kit/modifiers": "7.0.0",
"@dnd-kit/sortable": "8.0.0",
"@grafana/data": "^9.5.2",
"@mdx-js/loader": "2.3.0",
"@mdx-js/react": "2.3.0",
@@ -36,9 +39,9 @@
"@uiw/react-md-editor": "3.23.5",
"@xstate/react": "^3.0.0",
"ansi-to-html": "0.7.2",
"antd": "5.0.5",
"antd": "5.11.0",
"antd-table-saveas-excel": "2.2.1",
"axios": "^0.21.0",
"axios": "1.6.2",
"babel-eslint": "^10.1.0",
"babel-jest": "^29.6.4",
"babel-loader": "9.1.3",
@@ -80,13 +83,14 @@
"react-dnd-html5-backend": "16.0.1",
"react-dom": "18.2.0",
"react-drag-listview": "2.0.0",
"react-error-boundary": "4.0.11",
"react-force-graph": "^1.43.0",
"react-full-screen": "1.1.1",
"react-grid-layout": "^1.3.4",
"react-helmet-async": "1.3.0",
"react-i18next": "^11.16.1",
"react-intersection-observer": "9.4.1",
"react-markdown": "8.0.7",
"react-query": "^3.34.19",
"react-query": "3.39.3",
"react-redux": "^7.2.2",
"react-router-dom": "^5.2.0",
"react-syntax-highlighter": "15.5.0",
@@ -102,6 +106,7 @@
"ts-node": "^10.2.1",
"tsconfig-paths-webpack-plugin": "^3.5.1",
"typescript": "^4.0.5",
"uplot": "1.6.26",
"uuid": "^8.3.2",
"web-vitals": "^0.2.4",
"webpack": "5.88.2",

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1 @@
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80" width="2500" height="2500"><style>.st0{fill:#f3bd19}.st1{fill:#231f20}.st2{fill:#3ebeb0}.st3{fill:#37a595}.st4{fill:none}</style><path class="st0" d="M41.1 41.9H15.6V12.5h7.7c9.9 0 17.8 8 17.8 17.8v11.6z"/><path class="st1" d="M41.1 67.5c-14.1 0-25.6-11.4-25.6-25.6h25.6v25.6z"/><path class="st2" d="M41.1 41.9h23.3v25.6H41.1z"/><path class="st3" d="M41.1 41.9h5.4v25.6h-5.4z"/><path class="st4" d="M0 0h80v80H0z"/></svg>

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -34,7 +34,7 @@
"button_returntorules": "Return to rules",
"button_cancelchanges": "Cancel",
"button_discard": "Discard",
"text_condition1": "Send a notification when the metric is",
"text_condition1": "Send a notification when",
"text_condition2": "the threshold",
"text_condition3": "during the last",
"option_5min": "5 mins",
@@ -109,5 +109,6 @@
"traces_based_alert_desc": "Send a notification when a condition occurs in the traces data.",
"exceptions_based_alert": "Exceptions-based Alert",
"exceptions_based_alert_desc": "Send a notification when a condition occurs in the exceptions data.",
"field_unit": "Threshold unit"
"field_unit": "Threshold unit",
"selected_query_placeholder": "Select query"
}

View File

@@ -20,5 +20,10 @@
"variable_updated_successfully": "Variable updated successfully",
"error_while_updating_variable": "Error while updating variable",
"dashboard_has_been_updated": "Dashboard has been updated",
"do_you_want_to_refresh_the_dashboard": "Do you want to refresh the dashboard?"
"do_you_want_to_refresh_the_dashboard": "Do you want to refresh the dashboard?",
"delete_dashboard_success": "{{name}} dashboard deleted successfully",
"dashboard_unsave_changes": "There are unsaved changes in the Query builder, please stage and run the query or the changes will be lost. Press OK to discard.",
"dashboard_save_changes": "Your graph built with {{queryTag}} query will be saved. Press OK to confirm.",
"your_graph_build_with": "Your graph built with",
"dashboar_ok_confirm": "query will be saved. Press OK to confirm."
}

View File

@@ -14,5 +14,6 @@
"delete_domain_message": "Are you sure you want to delete this domain?",
"delete_domain": "Delete Domain",
"add_domain": "Add Domains",
"saml_settings":"Your SAML settings have been saved, please login from incognito window to confirm that it has been set up correctly"
"saml_settings": "Your SAML settings have been saved, please login from incognito window to confirm that it has been set up correctly",
"invite_link_share_manually": "After inviting members, please copy the invite link and send them the link manually"
}

View File

@@ -1,85 +1,85 @@
{
"preview_chart_unexpected_error": "An unexpeced error occurred updating the chart, please check your query.",
"preview_chart_threshold_label": "Threshold",
"placeholder_label_key_pair": "Click here to enter a label (key value pairs)",
"button_yes": "Yes",
"button_no": "No",
"remove_label_confirm": "This action will remove all the labels. Do you want to proceed?",
"remove_label_success": "Labels cleared",
"alert_form_step1": "Step 1 - Define the metric",
"alert_form_step2": "Step 2 - Define Alert Conditions",
"alert_form_step3": "Step 3 - Alert Configuration",
"metric_query_max_limit": "Can not create query. You can create maximum of 5 queries",
"confirm_save_title": "Save Changes",
"confirm_save_content_part1": "Your alert built with",
"confirm_save_content_part2": "query will be saved. Press OK to confirm.",
"unexpected_error": "Sorry, an unexpected error occurred. Please contact your admin",
"rule_created": "Rule created successfully",
"rule_edited": "Rule edited successfully",
"expression_missing": "expression is missing in {{where}}",
"metricname_missing": "metric name is missing in {{where}}",
"condition_required": "at least one metric condition is required",
"alertname_required": "alert name is required",
"promql_required": "promql expression is required when query format is set to PromQL",
"button_savechanges": "Save Rule",
"button_createrule": "Create Rule",
"button_returntorules": "Return to rules",
"button_cancelchanges": "Cancel",
"button_discard": "Discard",
"text_condition1": "Send a notification when the metric is",
"text_condition2": "the threshold",
"text_condition3": "during the last",
"option_5min": "5 mins",
"option_10min": "10 mins",
"option_15min": "15 mins",
"option_60min": "60 mins",
"option_4hours": "4 hours",
"option_24hours": "24 hours",
"field_threshold": "Alert Threshold",
"option_allthetimes": "all the times",
"option_atleastonce": "at least once",
"option_onaverage": "on average",
"option_intotal": "in total",
"option_above": "above",
"option_below": "below",
"option_equal": "is equal to",
"option_notequal": "not equal to",
"button_query": "Query",
"button_formula": "Formula",
"tab_qb": "Query Builder",
"tab_promql": "PromQL",
"title_confirm": "Confirm",
"button_ok": "Yes",
"button_cancel": "No",
"field_promql_expr": "PromQL Expression",
"field_alert_name": "Alert Name",
"field_alert_desc": "Alert Description",
"field_labels": "Labels",
"field_severity": "Severity",
"option_critical": "Critical",
"option_error": "Error",
"option_warning": "Warning",
"option_info": "Info",
"user_guide_headline": "Steps to create an Alert",
"user_guide_qb_step1": "Step 1 - Define the metric",
"user_guide_qb_step1a": "Choose a metric which you want to create an alert on",
"user_guide_qb_step1b": "Filter it based on WHERE field or GROUPBY if needed",
"user_guide_qb_step1c": "Apply an aggregatiion function like COUNT, SUM, etc. or choose NOOP to plot the raw metric",
"user_guide_qb_step1d": "Create a formula based on Queries if needed",
"user_guide_qb_step2": "Step 2 - Define Alert Conditions",
"user_guide_qb_step2a": "Select the evaluation interval, threshold type and whether you want to alert above/below a value",
"user_guide_qb_step2b": "Enter the Alert threshold",
"user_guide_qb_step3": "Step 3 -Alert Configuration",
"user_guide_qb_step3a": "Set alert severity, name and descriptions",
"user_guide_qb_step3b": "Add tags to the alert in the Label field if needed",
"user_guide_pql_step1": "Step 1 - Define the metric",
"user_guide_pql_step1a": "Write a PromQL query for the metric",
"user_guide_pql_step1b": "Format the legends based on labels you want to highlight",
"user_guide_pql_step2": "Step 2 - Define Alert Conditions",
"user_guide_pql_step2a": "Select the threshold type and whether you want to alert above/below a value",
"user_guide_pql_step2b": "Enter the Alert threshold",
"user_guide_pql_step3": "Step 3 -Alert Configuration",
"user_guide_pql_step3a": "Set alert severity, name and descriptions",
"user_guide_pql_step3b": "Add tags to the alert in the Label field if needed",
"user_tooltip_more_help": "More details on how to create alerts"
}
"preview_chart_unexpected_error": "An unexpeced error occurred updating the chart, please check your query.",
"preview_chart_threshold_label": "Threshold",
"placeholder_label_key_pair": "Click here to enter a label (key value pairs)",
"button_yes": "Yes",
"button_no": "No",
"remove_label_confirm": "This action will remove all the labels. Do you want to proceed?",
"remove_label_success": "Labels cleared",
"alert_form_step1": "Step 1 - Define the metric",
"alert_form_step2": "Step 2 - Define Alert Conditions",
"alert_form_step3": "Step 3 - Alert Configuration",
"metric_query_max_limit": "Can not create query. You can create maximum of 5 queries",
"confirm_save_title": "Save Changes",
"confirm_save_content_part1": "Your alert built with",
"confirm_save_content_part2": "query will be saved. Press OK to confirm.",
"unexpected_error": "Sorry, an unexpected error occurred. Please contact your admin",
"rule_created": "Rule created successfully",
"rule_edited": "Rule edited successfully",
"expression_missing": "expression is missing in {{where}}",
"metricname_missing": "metric name is missing in {{where}}",
"condition_required": "at least one metric condition is required",
"alertname_required": "alert name is required",
"promql_required": "promql expression is required when query format is set to PromQL",
"button_savechanges": "Save Rule",
"button_createrule": "Create Rule",
"button_returntorules": "Return to rules",
"button_cancelchanges": "Cancel",
"button_discard": "Discard",
"text_condition1": "Send a notification when",
"text_condition2": "the threshold",
"text_condition3": "during the last",
"option_5min": "5 mins",
"option_10min": "10 mins",
"option_15min": "15 mins",
"option_60min": "60 mins",
"option_4hours": "4 hours",
"option_24hours": "24 hours",
"field_threshold": "Alert Threshold",
"option_allthetimes": "all the times",
"option_atleastonce": "at least once",
"option_onaverage": "on average",
"option_intotal": "in total",
"option_above": "above",
"option_below": "below",
"option_equal": "is equal to",
"option_notequal": "not equal to",
"button_query": "Query",
"button_formula": "Formula",
"tab_qb": "Query Builder",
"tab_promql": "PromQL",
"title_confirm": "Confirm",
"button_ok": "Yes",
"button_cancel": "No",
"field_promql_expr": "PromQL Expression",
"field_alert_name": "Alert Name",
"field_alert_desc": "Alert Description",
"field_labels": "Labels",
"field_severity": "Severity",
"option_critical": "Critical",
"option_error": "Error",
"option_warning": "Warning",
"option_info": "Info",
"user_guide_headline": "Steps to create an Alert",
"user_guide_qb_step1": "Step 1 - Define the metric",
"user_guide_qb_step1a": "Choose a metric which you want to create an alert on",
"user_guide_qb_step1b": "Filter it based on WHERE field or GROUPBY if needed",
"user_guide_qb_step1c": "Apply an aggregatiion function like COUNT, SUM, etc. or choose NOOP to plot the raw metric",
"user_guide_qb_step1d": "Create a formula based on Queries if needed",
"user_guide_qb_step2": "Step 2 - Define Alert Conditions",
"user_guide_qb_step2a": "Select the evaluation interval, threshold type and whether you want to alert above/below a value",
"user_guide_qb_step2b": "Enter the Alert threshold",
"user_guide_qb_step3": "Step 3 -Alert Configuration",
"user_guide_qb_step3a": "Set alert severity, name and descriptions",
"user_guide_qb_step3b": "Add tags to the alert in the Label field if needed",
"user_guide_pql_step1": "Step 1 - Define the metric",
"user_guide_pql_step1a": "Write a PromQL query for the metric",
"user_guide_pql_step1b": "Format the legends based on labels you want to highlight",
"user_guide_pql_step2": "Step 2 - Define Alert Conditions",
"user_guide_pql_step2a": "Select the threshold type and whether you want to alert above/below a value",
"user_guide_pql_step2b": "Enter the Alert threshold",
"user_guide_pql_step3": "Step 3 -Alert Configuration",
"user_guide_pql_step3a": "Set alert severity, name and descriptions",
"user_guide_pql_step3b": "Add tags to the alert in the Label field if needed",
"user_tooltip_more_help": "More details on how to create alerts"
}

View File

@@ -0,0 +1,3 @@
{
"rps_over_100": "You are sending data at more than 100 RPS, your ingestion may be rate limited. Please reach out to us via Intercom support."
}

View File

@@ -34,7 +34,7 @@
"button_returntorules": "Return to rules",
"button_cancelchanges": "Cancel",
"button_discard": "Discard",
"text_condition1": "Send a notification when the metric is",
"text_condition1": "Send a notification when",
"text_condition2": "the threshold",
"text_condition3": "during the last",
"option_5min": "5 mins",
@@ -109,5 +109,6 @@
"traces_based_alert_desc": "Send a notification when a condition occurs in the traces data.",
"exceptions_based_alert": "Exceptions-based Alert",
"exceptions_based_alert_desc": "Send a notification when a condition occurs in the exceptions data.",
"field_unit": "Threshold unit"
"field_unit": "Threshold unit",
"selected_query_placeholder": "Select query"
}

View File

@@ -17,8 +17,16 @@
"layout_saved_successfully": "Layout saved successfully",
"add_panel": "Add Panel",
"save_layout": "Save Layout",
"full_view": "Full Screen View",
"variable_updated_successfully": "Variable updated successfully",
"error_while_updating_variable": "Error while updating variable",
"dashboard_has_been_updated": "Dashboard has been updated",
"do_you_want_to_refresh_the_dashboard": "Do you want to refresh the dashboard?"
"do_you_want_to_refresh_the_dashboard": "Do you want to refresh the dashboard?",
"locked_dashboard_delete_tooltip_admin_author": "Dashboard is locked. Please unlock the dashboard to enable delete.",
"locked_dashboard_delete_tooltip_editor": "Dashboard is locked. Please contact admin to delete the dashboard.",
"delete_dashboard_success": "{{name}} dashboard deleted successfully",
"dashboard_unsave_changes": "There are unsaved changes in the Query builder, please stage and run the query or the changes will be lost. Press OK to discard.",
"dashboard_save_changes": "Your graph built with {{queryTag}} query will be saved. Press OK to confirm.",
"your_graph_build_with": "Your graph built with",
"dashboar_ok_confirm": "query will be saved. Press OK to confirm."
}

View File

@@ -3,5 +3,7 @@
"see_error_in_trace_graph": "See the error in trace graph",
"stack_trace": "Stacktrace",
"older": "Older",
"newer": "Newer"
"newer": "Newer",
"something_went_wrong": "Oops !!! Something went wrong",
"contact_if_issue_exists": "Don't worry, our team is here to help. Please contact support if the issue persists."
}

View File

@@ -14,5 +14,6 @@
"delete_domain_message": "Are you sure you want to delete this domain?",
"delete_domain": "Delete Domain",
"add_domain": "Add Domains",
"saml_settings":"Your SAML settings have been saved, please login from incognito window to confirm that it has been set up correctly"
"saml_settings": "Your SAML settings have been saved, please login from incognito window to confirm that it has been set up correctly",
"invite_link_share_manually": "After inviting members, please copy the invite link and send them the link manually"
}

View File

@@ -5,6 +5,7 @@
"create": "Create",
"reorder": "Reorder",
"cancel": "Cancel",
"learn_more": "Learn more about pipelines",
"reorder_pipeline": "Do you want to reorder pipeline?",
"reorder_pipeline_description": "Logs are processed sequentially in processors and pipelines. Reordering it may change how data is processed by them.",
"delete_pipeline": "Do you want to delete pipeline",
@@ -31,15 +32,15 @@
"processor_name_placeholder": "Name",
"processor_regex_placeholder": "Regex",
"processor_parsefrom_placeholder": "Parse From",
"processor_parseto_placeholder": "Parse From",
"processor_parseto_placeholder": "Parse To",
"processor_onerror_placeholder": "on Error",
"processor_pattern_placeholder": "Pattern",
"processor_field_placeholder": "Field",
"processor_value_placeholder": "Value",
"processor_description_placeholder": "example rule: %{word:first}",
"processor_trace_id_placeholder": "Trace Id Parce From",
"processor_span_id_placeholder": "Span id Parse From",
"processor_trace_flags_placeholder": "Trace flags parse from",
"processor_trace_id_placeholder": "Parse Trace ID from",
"processor_span_id_placeholder": "Parse Span ID from",
"processor_trace_flags_placeholder": "Parse Trace flags from",
"processor_from_placeholder": "From",
"processor_to_placeholder": "To"
}

View File

@@ -1,85 +1,85 @@
{
"preview_chart_unexpected_error": "An unexpeced error occurred updating the chart, please check your query.",
"preview_chart_threshold_label": "Threshold",
"placeholder_label_key_pair": "Click here to enter a label (key value pairs)",
"button_yes": "Yes",
"button_no": "No",
"remove_label_confirm": "This action will remove all the labels. Do you want to proceed?",
"remove_label_success": "Labels cleared",
"alert_form_step1": "Step 1 - Define the metric",
"alert_form_step2": "Step 2 - Define Alert Conditions",
"alert_form_step3": "Step 3 - Alert Configuration",
"metric_query_max_limit": "Can not create query. You can create maximum of 5 queries",
"confirm_save_title": "Save Changes",
"confirm_save_content_part1": "Your alert built with",
"confirm_save_content_part2": "query will be saved. Press OK to confirm.",
"unexpected_error": "Sorry, an unexpected error occurred. Please contact your admin",
"rule_created": "Rule created successfully",
"rule_edited": "Rule edited successfully",
"expression_missing": "expression is missing in {{where}}",
"metricname_missing": "metric name is missing in {{where}}",
"condition_required": "at least one metric condition is required",
"alertname_required": "alert name is required",
"promql_required": "promql expression is required when query format is set to PromQL",
"button_savechanges": "Save Rule",
"button_createrule": "Create Rule",
"button_returntorules": "Return to rules",
"button_cancelchanges": "Cancel",
"button_discard": "Discard",
"text_condition1": "Send a notification when the metric is",
"text_condition2": "the threshold",
"text_condition3": "during the last",
"option_5min": "5 mins",
"option_10min": "10 mins",
"option_15min": "15 mins",
"option_60min": "60 mins",
"option_4hours": "4 hours",
"option_24hours": "24 hours",
"field_threshold": "Alert Threshold",
"option_allthetimes": "all the times",
"option_atleastonce": "at least once",
"option_onaverage": "on average",
"option_intotal": "in total",
"option_above": "above",
"option_below": "below",
"option_equal": "is equal to",
"option_notequal": "not equal to",
"button_query": "Query",
"button_formula": "Formula",
"tab_qb": "Query Builder",
"tab_promql": "PromQL",
"title_confirm": "Confirm",
"button_ok": "Yes",
"button_cancel": "No",
"field_promql_expr": "PromQL Expression",
"field_alert_name": "Alert Name",
"field_alert_desc": "Alert Description",
"field_labels": "Labels",
"field_severity": "Severity",
"option_critical": "Critical",
"option_error": "Error",
"option_warning": "Warning",
"option_info": "Info",
"user_guide_headline": "Steps to create an Alert",
"user_guide_qb_step1": "Step 1 - Define the metric",
"user_guide_qb_step1a": "Choose a metric which you want to create an alert on",
"user_guide_qb_step1b": "Filter it based on WHERE field or GROUPBY if needed",
"user_guide_qb_step1c": "Apply an aggregatiion function like COUNT, SUM, etc. or choose NOOP to plot the raw metric",
"user_guide_qb_step1d": "Create a formula based on Queries if needed",
"user_guide_qb_step2": "Step 2 - Define Alert Conditions",
"user_guide_qb_step2a": "Select the evaluation interval, threshold type and whether you want to alert above/below a value",
"user_guide_qb_step2b": "Enter the Alert threshold",
"user_guide_qb_step3": "Step 3 -Alert Configuration",
"user_guide_qb_step3a": "Set alert severity, name and descriptions",
"user_guide_qb_step3b": "Add tags to the alert in the Label field if needed",
"user_guide_pql_step1": "Step 1 - Define the metric",
"user_guide_pql_step1a": "Write a PromQL query for the metric",
"user_guide_pql_step1b": "Format the legends based on labels you want to highlight",
"user_guide_pql_step2": "Step 2 - Define Alert Conditions",
"user_guide_pql_step2a": "Select the threshold type and whether you want to alert above/below a value",
"user_guide_pql_step2b": "Enter the Alert threshold",
"user_guide_pql_step3": "Step 3 -Alert Configuration",
"user_guide_pql_step3a": "Set alert severity, name and descriptions",
"user_guide_pql_step3b": "Add tags to the alert in the Label field if needed",
"user_tooltip_more_help": "More details on how to create alerts"
}
"preview_chart_unexpected_error": "An unexpeced error occurred updating the chart, please check your query.",
"preview_chart_threshold_label": "Threshold",
"placeholder_label_key_pair": "Click here to enter a label (key value pairs)",
"button_yes": "Yes",
"button_no": "No",
"remove_label_confirm": "This action will remove all the labels. Do you want to proceed?",
"remove_label_success": "Labels cleared",
"alert_form_step1": "Step 1 - Define the metric",
"alert_form_step2": "Step 2 - Define Alert Conditions",
"alert_form_step3": "Step 3 - Alert Configuration",
"metric_query_max_limit": "Can not create query. You can create maximum of 5 queries",
"confirm_save_title": "Save Changes",
"confirm_save_content_part1": "Your alert built with",
"confirm_save_content_part2": "query will be saved. Press OK to confirm.",
"unexpected_error": "Sorry, an unexpected error occurred. Please contact your admin",
"rule_created": "Rule created successfully",
"rule_edited": "Rule edited successfully",
"expression_missing": "expression is missing in {{where}}",
"metricname_missing": "metric name is missing in {{where}}",
"condition_required": "at least one metric condition is required",
"alertname_required": "alert name is required",
"promql_required": "promql expression is required when query format is set to PromQL",
"button_savechanges": "Save Rule",
"button_createrule": "Create Rule",
"button_returntorules": "Return to rules",
"button_cancelchanges": "Cancel",
"button_discard": "Discard",
"text_condition1": "Send a notification when",
"text_condition2": "the threshold",
"text_condition3": "during the last",
"option_5min": "5 mins",
"option_10min": "10 mins",
"option_15min": "15 mins",
"option_60min": "60 mins",
"option_4hours": "4 hours",
"option_24hours": "24 hours",
"field_threshold": "Alert Threshold",
"option_allthetimes": "all the times",
"option_atleastonce": "at least once",
"option_onaverage": "on average",
"option_intotal": "in total",
"option_above": "above",
"option_below": "below",
"option_equal": "is equal to",
"option_notequal": "not equal to",
"button_query": "Query",
"button_formula": "Formula",
"tab_qb": "Query Builder",
"tab_promql": "PromQL",
"title_confirm": "Confirm",
"button_ok": "Yes",
"button_cancel": "No",
"field_promql_expr": "PromQL Expression",
"field_alert_name": "Alert Name",
"field_alert_desc": "Alert Description",
"field_labels": "Labels",
"field_severity": "Severity",
"option_critical": "Critical",
"option_error": "Error",
"option_warning": "Warning",
"option_info": "Info",
"user_guide_headline": "Steps to create an Alert",
"user_guide_qb_step1": "Step 1 - Define the metric",
"user_guide_qb_step1a": "Choose a metric which you want to create an alert on",
"user_guide_qb_step1b": "Filter it based on WHERE field or GROUPBY if needed",
"user_guide_qb_step1c": "Apply an aggregatiion function like COUNT, SUM, etc. or choose NOOP to plot the raw metric",
"user_guide_qb_step1d": "Create a formula based on Queries if needed",
"user_guide_qb_step2": "Step 2 - Define Alert Conditions",
"user_guide_qb_step2a": "Select the evaluation interval, threshold type and whether you want to alert above/below a value",
"user_guide_qb_step2b": "Enter the Alert threshold",
"user_guide_qb_step3": "Step 3 -Alert Configuration",
"user_guide_qb_step3a": "Set alert severity, name and descriptions",
"user_guide_qb_step3b": "Add tags to the alert in the Label field if needed",
"user_guide_pql_step1": "Step 1 - Define the metric",
"user_guide_pql_step1a": "Write a PromQL query for the metric",
"user_guide_pql_step1b": "Format the legends based on labels you want to highlight",
"user_guide_pql_step2": "Step 2 - Define Alert Conditions",
"user_guide_pql_step2a": "Select the threshold type and whether you want to alert above/below a value",
"user_guide_pql_step2b": "Enter the Alert threshold",
"user_guide_pql_step3": "Step 3 -Alert Configuration",
"user_guide_pql_step3a": "Set alert severity, name and descriptions",
"user_guide_pql_step3b": "Add tags to the alert in the Label field if needed",
"user_tooltip_more_help": "More details on how to create alerts"
}

View File

@@ -0,0 +1,3 @@
{
"rps_over_100": "You are sending data at more than 100 RPS, your ingestion may be rate limited. Please reach out to us via Intercom support."
}

View File

@@ -32,6 +32,7 @@
"LOGS": "SigNoz | Logs",
"LOGS_EXPLORER": "SigNoz | Logs Explorer",
"LIVE_LOGS": "SigNoz | Live Logs",
"LOGS_PIPELINES": "SigNoz | Logs Pipelines",
"HOME_PAGE": "Open source Observability Platform | SigNoz",
"PASSWORD_RESET": "SigNoz | Password Reset",
"LIST_LICENSES": "SigNoz | List of Licenses",

View File

@@ -0,0 +1,3 @@
{
"this_value_satisfies_multiple_thresholds": "This value satisfies multiple thresholds."
}

View File

@@ -39,10 +39,12 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
[pathname],
);
const { data: licensesData } = useLicense();
const {
data: licensesData,
isFetching: isFetchingLicensesData,
} = useLicense();
const {
user,
isUserFetching,
isUserFetchingError,
isLoggedIn: isLoggedInState,
@@ -116,7 +118,7 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
if (
localStorageUserAuthToken &&
localStorageUserAuthToken.refreshJwt &&
user?.userId === ''
isUserFetching
) {
handleUserLoginIfTokenPresent(key);
} else {
@@ -131,28 +133,34 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
if (path && path !== ROUTES.WORKSPACE_LOCKED) {
history.push(ROUTES.WORKSPACE_LOCKED);
}
dispatch({
type: UPDATE_USER_IS_FETCH,
payload: {
isUserFetching: false,
},
});
dispatch({
type: UPDATE_USER_IS_FETCH,
payload: {
isUserFetching: false,
},
});
}
};
useEffect(() => {
if (!isFetchingLicensesData) {
const shouldBlockWorkspace = licensesData?.payload?.workSpaceBlock;
if (shouldBlockWorkspace) {
navigateToWorkSpaceBlocked(currentRoute);
}
}
}, [isFetchingLicensesData]);
// eslint-disable-next-line sonarjs/cognitive-complexity
useEffect(() => {
(async (): Promise<void> => {
try {
const shouldBlockWorkspace = licensesData?.payload?.workSpaceBlock;
if (currentRoute) {
const { isPrivate, key } = currentRoute;
if (shouldBlockWorkspace) {
navigateToWorkSpaceBlocked(currentRoute);
} else if (isPrivate) {
if (isPrivate && key !== ROUTES.WORKSPACE_LOCKED) {
handlePrivateRoutes(key);
} else {
// no need to fetch the user and make user fetching false

View File

@@ -7,12 +7,14 @@ import { FeatureKeys } from 'constants/features';
import { LOCALSTORAGE } from 'constants/localStorage';
import ROUTES from 'constants/routes';
import AppLayout from 'container/AppLayout';
import useAnalytics from 'hooks/analytics/useAnalytics';
import { useThemeConfig } from 'hooks/useDarkMode';
import useGetFeatureFlag from 'hooks/useGetFeatureFlag';
import useLicense, { LICENSE_PLAN_KEY } from 'hooks/useLicense';
import { NotificationProvider } from 'hooks/useNotifications';
import { ResourceProvider } from 'hooks/useResourceAttribute';
import history from 'lib/history';
import { identity, pickBy } from 'lodash-es';
import { DashboardProvider } from 'providers/Dashboard/Dashboard';
import { QueryBuilderProvider } from 'providers/QueryBuilder';
import { Suspense, useEffect, useState } from 'react';
@@ -24,7 +26,6 @@ import AppActions from 'types/actions';
import { UPDATE_FEATURE_FLAG_RESPONSE } from 'types/actions/app';
import AppReducer, { User } from 'types/reducer/app';
import { extractDomain, isCloudUser, isEECloudUser } from 'utils/app';
import { trackPageView } from 'utils/segmentAnalytics';
import PrivateRoute from './Private';
import defaultRoutes, { AppRoutes, SUPPORT_ROUTE } from './routes';
@@ -40,6 +41,8 @@ function App(): JSX.Element {
const dispatch = useDispatch<Dispatch<AppActions>>();
const { trackPageView } = useAnalytics();
const { hostname, pathname } = window.location;
const isCloudUserVal = isCloudUser();
@@ -90,13 +93,19 @@ function App(): JSX.Element {
const orgName =
org && Array.isArray(org) && org.length > 0 ? org[0].name : '';
const { name, email } = user;
const identifyPayload = {
email: user?.email,
name: user?.name,
email,
name,
company_name: orgName,
role,
source: 'signoz-ui',
};
const domain = extractDomain(user?.email);
const sanitizedIdentifyPayload = pickBy(identifyPayload, identity);
const domain = extractDomain(email);
const hostNameParts = hostname.split('.');
@@ -106,13 +115,14 @@ function App(): JSX.Element {
data_region: hostNameParts[1],
tenant_url: hostname,
company_domain: domain,
source: 'signoz-ui',
};
window.analytics.identify(user?.email, identifyPayload);
window.analytics.identify(email, sanitizedIdentifyPayload);
window.analytics.group(domain, groupTraits);
window.clarity('identify', user.email, user.name);
window.clarity('identify', email, name);
};
useEffect(() => {
@@ -148,6 +158,7 @@ function App(): JSX.Element {
useEffect(() => {
trackPageView(pathname);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pathname]);
return (

View File

@@ -49,7 +49,8 @@ export const Onboarding = Loadable(
);
export const DashboardPage = Loadable(
() => import(/* webpackChunkName: "DashboardPage" */ 'pages/Dashboard'),
() =>
import(/* webpackChunkName: "DashboardPage" */ 'pages/DashboardsListPage'),
);
export const NewDashboardPage = Loadable(

View File

@@ -282,10 +282,10 @@ const routes: AppRoutes[] = [
isPrivate: false,
},
{
path: ROUTES.PIPELINES,
path: ROUTES.LOGS_PIPELINES,
exact: true,
component: PipelinePage,
key: 'PIPELINES',
key: 'LOGS_PIPELINES',
isPrivate: true,
},
{
@@ -299,7 +299,7 @@ const routes: AppRoutes[] = [
path: ROUTES.WORKSPACE_LOCKED,
exact: true,
component: WorkspaceBlocked,
isPrivate: false,
isPrivate: true,
key: 'WORKSPACE_LOCKED',
},
];

View File

@@ -1,4 +1,4 @@
import { AxiosError } from 'axios';
import { AxiosError, AxiosResponse } from 'axios';
import { ErrorResponse } from 'types/api';
import { ErrorStatusCode } from 'types/common';
@@ -10,7 +10,7 @@ export function ErrorResponseHandler(error: AxiosError): ErrorResponse {
const statusCode = response.status as ErrorStatusCode;
if (statusCode >= 400 && statusCode < 500) {
const { data } = response;
const { data } = response as AxiosResponse;
if (statusCode === 404) {
return {

View File

@@ -3,9 +3,9 @@ import { ApiResponse } from 'types/api';
import { Props } from 'types/api/dashboard/get';
import { Dashboard } from 'types/api/dashboard/getAll';
const get = (props: Props): Promise<Dashboard> =>
const getDashboard = (props: Props): Promise<Dashboard> =>
axios
.get<ApiResponse<Dashboard>>(`/dashboards/${props.uuid}`)
.then((res) => res.data.data);
export default get;
export default getDashboard;

View File

@@ -0,0 +1,11 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
interface LockDashboardProps {
uuid: string;
}
const lockDashboard = (props: LockDashboardProps): Promise<AxiosResponse> =>
axios.put(`/dashboards/${props.uuid}/lock`);
export default lockDashboard;

View File

@@ -0,0 +1,15 @@
import { ApiV3Instance as axios } from 'api';
import { ApiResponse } from 'types/api';
import { ICompositeMetricQuery } from 'types/api/alerts/compositeQuery';
import { QueryRangePayload } from 'types/api/metrics/getQueryRange';
interface IQueryRangeFormat {
compositeQuery: ICompositeMetricQuery;
}
export const getQueryRangeFormat = (
props?: Partial<QueryRangePayload>,
): Promise<IQueryRangeFormat> =>
axios
.post<ApiResponse<IQueryRangeFormat>>('/query_range/format', props)
.then((res) => res.data.data);

View File

@@ -0,0 +1,11 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
interface UnlockDashboardProps {
uuid: string;
}
const unlockDashboard = (props: UnlockDashboardProps): Promise<AxiosResponse> =>
axios.put(`/dashboards/${props.uuid}/unlock`);
export default unlockDashboard;

View File

@@ -4,7 +4,7 @@ import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/dashboard/update';
const update = async (
const updateDashboard = async (
props: Props,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
@@ -23,4 +23,4 @@ const update = async (
}
};
export default update;
export default updateDashboard;

View File

@@ -0,0 +1,30 @@
import { ApiV2Instance as axios } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
Props,
VariableResponseProps,
} from 'types/api/dashboard/variables/query';
const dashboardVariablesQuery = async (
props: Props,
): Promise<SuccessResponse<VariableResponseProps> | ErrorResponse> => {
try {
const response = await axios.post(`/variables/query`, props);
return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
const formattedError = ErrorResponseHandler(error as AxiosError);
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw { message: 'Error fetching data', details: formattedError };
}
};
export default dashboardVariablesQuery;

View File

@@ -1,24 +0,0 @@
import { ApiV2Instance as axios } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/dashboard/variables/query';
const query = async (
props: Props,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
const response = await axios.post(`/variables/query`, props);
return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default query;

View File

@@ -4,7 +4,7 @@
import getLocalStorageApi from 'api/browser/localstorage/get';
import loginApi from 'api/user/login';
import afterLogin from 'AppRoutes/utils';
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
import axios, { AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { ENVIRONMENT } from 'constants/env';
import { LOCALSTORAGE } from 'constants/localStorage';
import store from 'store';
@@ -17,14 +17,16 @@ const interceptorsResponse = (
): Promise<AxiosResponse<any>> => Promise.resolve(value);
const interceptorsRequestResponse = (
value: AxiosRequestConfig,
): AxiosRequestConfig => {
value: InternalAxiosRequestConfig,
): InternalAxiosRequestConfig => {
const token =
store.getState().app.user?.accessJwt ||
getLocalStorageApi(LOCALSTORAGE.AUTH_TOKEN) ||
'';
value.headers.Authorization = token ? `Bearer ${token}` : '';
if (value && value.headers) {
value.headers.Authorization = token ? `Bearer ${token}` : '';
}
return value;
};
@@ -92,8 +94,8 @@ const instance = axios.create({
baseURL: `${ENVIRONMENT.baseURL}${apiV1}`,
});
instance.interceptors.response.use(interceptorsResponse, interceptorRejected);
instance.interceptors.request.use(interceptorsRequestResponse);
instance.interceptors.response.use(interceptorsResponse, interceptorRejected);
export const AxiosAlertManagerInstance = axios.create({
baseURL: `${ENVIRONMENT.baseURL}${apiAlertManager}`,

View File

@@ -9,9 +9,10 @@ import {
export const getMetricsQueryRange = async (
props: QueryRangePayload,
signal: AbortSignal,
): Promise<SuccessResponse<MetricRangePayloadV3> | ErrorResponse> => {
try {
const response = await axios.post('/query_range', props);
const response = await axios.post('/query_range', props, { signal });
return {
statusCode: 200,

View File

@@ -3,10 +3,10 @@
exports[`DraggableTableRow Snapshot test should render DraggableTableRow 1`] = `
<DocumentFragment>
<div
class="ant-table-wrapper css-dev-only-do-not-override-1i536d8"
class="ant-table-wrapper css-dev-only-do-not-override-2i2tap"
>
<div
class="ant-spin-nested-loading css-dev-only-do-not-override-1i536d8"
class="ant-spin-nested-loading css-dev-only-do-not-override-2i2tap"
>
<div
class="ant-spin-container"
@@ -28,7 +28,7 @@ exports[`DraggableTableRow Snapshot test should render DraggableTableRow 1`] = `
class="ant-table-thead"
>
<tr>
<th
<td
class="ant-table-cell"
/>
</tr>
@@ -43,7 +43,7 @@ exports[`DraggableTableRow Snapshot test should render DraggableTableRow 1`] = `
class="ant-table-cell"
>
<div
class="css-dev-only-do-not-override-1i536d8 ant-empty ant-empty-normal"
class="css-dev-only-do-not-override-2i2tap ant-empty ant-empty-normal"
>
<div
class="ant-empty-image"

View File

@@ -0,0 +1,11 @@
.dropdown-button {
color: #fff;
}
.dropdown-button--dark {
color: #000;
}
.dropdown-icon {
font-size: 1.2rem;
}

View File

@@ -0,0 +1,30 @@
import './DropDown.styles.scss';
import { EllipsisOutlined } from '@ant-design/icons';
import { Button, Dropdown, MenuProps } from 'antd';
import { useIsDarkMode } from 'hooks/useDarkMode';
function DropDown({ element }: { element: JSX.Element[] }): JSX.Element {
const isDarkMode = useIsDarkMode();
const items: MenuProps['items'] = element.map(
(e: JSX.Element, index: number) => ({
label: e,
key: index,
}),
);
return (
<Dropdown menu={{ items }}>
<Button
type="link"
className={!isDarkMode ? 'dropdown-button--dark' : 'dropdown-button'}
onClick={(e): void => e.preventDefault()}
>
<EllipsisOutlined className="dropdown-icon" />
</Button>
</Dropdown>
);
}
export default DropDown;

View File

@@ -220,7 +220,11 @@ function ExplorerCard({
open={isOpen}
onOpenChange={handleOpenChange}
>
<Button type={saveButtonType} icon={saveButtonIcon}>
<Button
type={saveButtonType}
icon={saveButtonIcon}
data-testid="traces-save-view-action"
>
{isQueryUpdated
? SaveButtonText.SAVE_AS_NEW_VIEW
: SaveButtonText.SAVE_VIEW}

View File

@@ -51,11 +51,10 @@ function SaveViewWithName({
return (
<Card>
<Typography>{t('name_of_the_view')}</Typography>
<Form form={form} onFinish={onSaveHandler}>
<Form form={form} onFinish={onSaveHandler} requiredMark>
<Form.Item
name={['viewName']}
required
requiredMark
rules={[
{
required: true,
@@ -65,7 +64,12 @@ function SaveViewWithName({
>
<Input placeholder="Enter Name" />
</Form.Item>
<SaveButton htmlType="submit" type="primary" loading={isLoading}>
<SaveButton
htmlType="submit"
type="primary"
loading={isLoading}
data-testid="save-view-name-action-button"
>
Save
</SaveButton>
</Form>

View File

@@ -5,6 +5,7 @@ import { QueryParams } from 'constants/query';
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
import isEqual from 'lodash-es/isEqual';
import { Query } from 'types/api/queryBuilder/queryBuilderData';
import {
DeleteViewHandlerProps,
@@ -35,6 +36,45 @@ export const getViewDetailsUsingViewKey: GetViewDetailsUsingViewKey = (
return undefined;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const omitIdFromQuery = (query: Query | null): any => ({
...query,
builder: {
...query?.builder,
queryData: query?.builder.queryData.map((queryData) => {
const { id, ...rest } = queryData.aggregateAttribute;
const newAggregateAttribute = rest;
const newGroupByAttributes = queryData.groupBy.map((groupByAttribute) => {
const { id, ...rest } = groupByAttribute;
return rest;
});
const newItems = queryData.filters.items.map((item) => {
const { id, ...newItem } = item;
if (item.key) {
const { id, ...rest } = item.key;
return {
...newItem,
key: rest,
};
}
return newItem;
});
return {
...queryData,
aggregateAttribute: newAggregateAttribute,
groupBy: newGroupByAttributes,
filters: {
...queryData.filters,
items: newItems,
},
limit: queryData.limit ? queryData.limit : 0,
offset: queryData.offset ? queryData.offset : 0,
pageSize: queryData.pageSize ? queryData.pageSize : 0,
};
}),
},
});
export const isQueryUpdatedInView = ({
viewKey,
data,
@@ -48,43 +88,7 @@ export const isQueryUpdatedInView = ({
const { query, panelType } = currentViewDetails;
// Omitting id from aggregateAttribute and groupBy
const updatedCurrentQuery = {
...stagedQuery,
builder: {
...stagedQuery?.builder,
queryData: stagedQuery?.builder.queryData.map((queryData) => {
const { id, ...rest } = queryData.aggregateAttribute;
const newAggregateAttribute = rest;
const newGroupByAttributes = queryData.groupBy.map((groupByAttribute) => {
const { id, ...rest } = groupByAttribute;
return rest;
});
const newItems = queryData.filters.items.map((item) => {
const { id, ...newItem } = item;
if (item.key) {
const { id, ...rest } = item.key;
return {
...newItem,
key: rest,
};
}
return newItem;
});
return {
...queryData,
aggregateAttribute: newAggregateAttribute,
groupBy: newGroupByAttributes,
filters: {
...queryData.filters,
items: newItems,
},
limit: queryData.limit ? queryData.limit : 0,
offset: queryData.offset ? queryData.offset : 0,
pageSize: queryData.pageSize ? queryData.pageSize : 0,
};
}),
},
};
const updatedCurrentQuery = omitIdFromQuery(stagedQuery);
return (
panelType !== currentPanelType ||
@@ -153,7 +157,7 @@ export const deleteViewHandler = ({
if (viewId === viewKey) {
redirectWithQueryBuilderData(
updateAllQueriesOperators(
initialQueriesMap.traces,
initialQueriesMap[sourcePage],
panelType || PANEL_TYPES.LIST,
sourcePage,
),

View File

@@ -35,7 +35,7 @@ export type GraphOnClickHandler = (
) => void;
export type ToggleGraphProps = {
toggleGraph(graphIndex: number, isVisible: boolean): void;
toggleGraph(graphIndex: number, isVisible: boolean, reference?: string): void;
};
export type CustomChartOptions = ChartOptions & {

View File

@@ -46,7 +46,7 @@ export const getYAxisFormattedValue = (
return `${parseFloat(value)}`;
};
export const getToolTipValue = (value: string, format: string): string => {
export const getToolTipValue = (value: string, format?: string): string => {
try {
return formattedValueToString(
getValueFormat(format)(parseFloat(value), undefined, undefined, undefined),

View File

@@ -7,7 +7,6 @@ import {
} from '@ant-design/icons';
import Convert from 'ansi-to-html';
import { Button, Divider, Row, Typography } from 'antd';
import LogDetail from 'components/LogDetail';
import LogsExplorerContext from 'container/LogsExplorerContext';
import dayjs from 'dayjs';
import dompurify from 'dompurify';
@@ -95,11 +94,15 @@ function LogSelectedField({
type ListLogViewProps = {
logData: ILog;
selectedFields: IField[];
onSetActiveLog: (log: ILog) => void;
onAddToQuery: AddToQueryHOCProps['onAddToQuery'];
};
function ListLogView({
logData,
selectedFields,
onSetActiveLog,
onAddToQuery,
}: ListLogViewProps): JSX.Element {
const flattenLogData = useMemo(() => FlatLogData(logData), [logData]);
@@ -113,12 +116,6 @@ function ListLogView({
onSetActiveLog: handleSetActiveContextLog,
onClearActiveLog: handleClearActiveContextLog,
} = useActiveLog();
const {
activeLog,
onSetActiveLog,
onClearActiveLog,
onAddToQuery,
} = useActiveLog();
const handleDetailedView = useCallback(() => {
onSetActiveLog(logData);
@@ -223,12 +220,6 @@ function ListLogView({
onClose={handleClearActiveContextLog}
/>
)}
<LogDetail
log={activeLog}
onClose={onClearActiveLog}
onAddToQuery={onAddToQuery}
onClickActionItem={onAddToQuery}
/>
</Row>
</Container>
);

View File

@@ -1,6 +1,8 @@
.code-snippet-container {
position: relative;
background-color: rgb(43, 43, 43);
// background-color: rgb(43, 43, 43);
background-color: #111a2c;
border-color: #111a2c;
}
.code-copy-btn {

View File

@@ -9,7 +9,7 @@ exports[`MessageTip custom action 1`] = `
}
<div
class="ant-alert ant-alert-info ant-alert-with-description c0 css-dev-only-do-not-override-1i536d8"
class="ant-alert ant-alert-info ant-alert-with-description c0 css-dev-only-do-not-override-2i2tap"
data-show="true"
role="alert"
>

View File

@@ -0,0 +1,25 @@
.DynamicColumnTable {
display: flex;
flex-direction: column;
width: 100%;
.dynamicColumnTable-button {
align-self: flex-end;
margin: 10px 0;
}
}
.dynamicColumnsTable-items {
display: flex;
width: 10.625rem;
justify-content: space-between;
align-items: center;
}
@media (max-width: 768px) {
.dynamicColumnsTable-items {
flex-direction: column;
width: auto;
text-align: center;
}
}

View File

@@ -0,0 +1,113 @@
/* eslint-disable react/jsx-props-no-spreading */
import './DynamicColumnTable.syles.scss';
import { SettingOutlined } from '@ant-design/icons';
import { Button, Dropdown, MenuProps, Switch } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import { memo, useEffect, useState } from 'react';
import { popupContainer } from 'utils/selectPopupContainer';
import ResizeTable from './ResizeTable';
import { DynamicColumnTableProps } from './types';
import {
getNewColumnData,
getVisibleColumns,
setVisibleColumns,
} from './utils';
function DynamicColumnTable({
tablesource,
columns,
dynamicColumns,
onDragColumn,
...restProps
}: DynamicColumnTableProps): JSX.Element {
const [columnsData, setColumnsData] = useState<ColumnsType | undefined>(
columns,
);
useEffect(() => {
setColumnsData(columns);
const visibleColumns = getVisibleColumns({
tablesource,
columnsData: columns,
dynamicColumns,
});
setColumnsData((prevColumns) =>
prevColumns
? [
...prevColumns.slice(0, prevColumns.length - 1),
...visibleColumns,
prevColumns[prevColumns.length - 1],
]
: undefined,
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [columns]);
const onToggleHandler = (index: number) => (
checked: boolean,
event: React.MouseEvent<HTMLButtonElement>,
): void => {
event.stopPropagation();
setVisibleColumns({
tablesource,
dynamicColumns,
index,
checked,
});
setColumnsData((prevColumns) =>
getNewColumnData({
checked,
index,
prevColumns,
dynamicColumns,
}),
);
};
const items: MenuProps['items'] =
dynamicColumns?.map((column, index) => ({
label: (
<div className="dynamicColumnsTable-items">
<div>{column.title?.toString()}</div>
<Switch
checked={columnsData?.findIndex((c) => c.key === column.key) !== -1}
onChange={onToggleHandler(index)}
/>
</div>
),
key: index,
type: 'checkbox',
})) || [];
return (
<div className="DynamicColumnTable">
{dynamicColumns && (
<Dropdown
getPopupContainer={popupContainer}
menu={{ items }}
trigger={['click']}
>
<Button
className="dynamicColumnTable-button"
size="middle"
icon={<SettingOutlined />}
/>
</Dropdown>
)}
<ResizeTable
columns={columnsData}
onDragColumn={onDragColumn}
{...restProps}
/>
</div>
);
}
DynamicColumnTable.defaultProps = {
onDragColumn: undefined,
};
export default memo(DynamicColumnTable);

View File

@@ -0,0 +1,15 @@
import { Typography } from 'antd';
import Time from './Time';
function DateComponent(
CreatedOrUpdateTime: string | number | Date,
): JSX.Element {
if (CreatedOrUpdateTime === null) {
return <Typography> - </Typography>;
}
return <Time CreatedOrUpdateTime={CreatedOrUpdateTime} />;
}
export default DateComponent;

View File

@@ -2,16 +2,15 @@ import { Typography } from 'antd';
import convertDateToAmAndPm from 'lib/convertDateToAmAndPm';
import getFormattedDate from 'lib/getFormatedDate';
import { Data } from '..';
function DateComponent(lastUpdatedTime: Data['lastUpdatedTime']): JSX.Element {
const time = new Date(lastUpdatedTime);
function Time({ CreatedOrUpdateTime }: DateProps): JSX.Element {
const time = new Date(CreatedOrUpdateTime);
const date = getFormattedDate(time);
const timeString = `${date} ${convertDateToAmAndPm(time)}`;
return <Typography>{timeString}</Typography>;
}
export default DateComponent;
type DateProps = {
CreatedOrUpdateTime: string | number | Date;
};
export default Time;

View File

@@ -0,0 +1,11 @@
export const TableDataSource = {
Alert: 'alert',
Dashboard: 'dashboard',
} as const;
export const DynamicColumnsKey = {
CreatedAt: 'createdAt',
CreatedBy: 'createdBy',
UpdatedAt: 'updatedAt',
UpdatedBy: 'updatedBy',
};

View File

@@ -1,6 +1,43 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { TableProps } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { ColumnGroupType, ColumnType } from 'antd/lib/table';
import { TableDataSource } from './contants';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface ResizeTableProps extends TableProps<any> {
onDragColumn?: (fromIndex: number, toIndex: number) => void;
}
export interface DynamicColumnTableProps extends TableProps<any> {
tablesource: typeof TableDataSource[keyof typeof TableDataSource];
dynamicColumns: TableProps<any>['columns'];
onDragColumn?: (fromIndex: number, toIndex: number) => void;
}
export type GetVisibleColumnsFunction = (
props: GetVisibleColumnProps,
) => (ColumnGroupType<any> | ColumnType<any>)[];
export type GetVisibleColumnProps = {
tablesource: typeof TableDataSource[keyof typeof TableDataSource];
dynamicColumns?: ColumnsType<any>;
columnsData?: ColumnsType;
};
export type SetVisibleColumnsProps = {
checked: boolean;
index: number;
tablesource: typeof TableDataSource[keyof typeof TableDataSource];
dynamicColumns?: ColumnsType<any>;
};
type GetNewColumnDataProps = {
prevColumns?: ColumnsType;
checked: boolean;
dynamicColumns?: ColumnsType<any>;
index: number;
};
export type GetNewColumnDataFunction = (
props: GetNewColumnDataProps,
) => ColumnsType | undefined;

View File

@@ -0,0 +1,77 @@
import { DynamicColumnsKey } from './contants';
import {
GetNewColumnDataFunction,
GetVisibleColumnsFunction,
SetVisibleColumnsProps,
} from './types';
export const getVisibleColumns: GetVisibleColumnsFunction = ({
tablesource,
dynamicColumns,
columnsData,
}) => {
let columnVisibilityData: { [key: string]: boolean };
try {
const storedData = localStorage.getItem(tablesource);
if (typeof storedData === 'string' && dynamicColumns) {
columnVisibilityData = JSON.parse(storedData);
return dynamicColumns.filter((column) => {
if (column.key && !columnsData?.find((c) => c.key === column.key)) {
return columnVisibilityData[column.key];
}
return false;
});
}
const initialColumnVisibility: Record<string, boolean> = {};
Object.values(DynamicColumnsKey).forEach((key) => {
initialColumnVisibility[key] = false;
});
localStorage.setItem(tablesource, JSON.stringify(initialColumnVisibility));
} catch (error) {
console.error(error);
}
return [];
};
export const setVisibleColumns = ({
checked,
index,
tablesource,
dynamicColumns,
}: SetVisibleColumnsProps): void => {
try {
const storedData = localStorage.getItem(tablesource);
if (typeof storedData === 'string' && dynamicColumns) {
const columnVisibilityData = JSON.parse(storedData);
const { key } = dynamicColumns[index];
if (key) {
columnVisibilityData[key] = checked;
}
localStorage.setItem(tablesource, JSON.stringify(columnVisibilityData));
}
} catch (error) {
console.error(error);
}
};
export const getNewColumnData: GetNewColumnDataFunction = ({
prevColumns,
checked,
dynamicColumns,
index,
}) => {
if (checked && dynamicColumns) {
return prevColumns
? [
...prevColumns.slice(0, prevColumns.length - 1),
dynamicColumns[index],
prevColumns[prevColumns.length - 1],
]
: undefined;
}
return prevColumns && dynamicColumns
? prevColumns.filter((column) => dynamicColumns[index].title !== column.title)
: undefined;
};

View File

@@ -0,0 +1,10 @@
.label-column {
display: flex;
flex-wrap: wrap;
.label-column--tag {
white-space: normal;
margin: 0.2rem 0.2rem;
}
}

View File

@@ -0,0 +1,54 @@
import './LabelColumn.styles.scss';
import { Popover, Tag } from 'antd';
import { popupContainer } from 'utils/selectPopupContainer';
import { LabelColumnProps } from './TableRenderer.types';
import TagWithToolTip from './TagWithToolTip';
function LabelColumn({ labels, value, color }: LabelColumnProps): JSX.Element {
const newLabels = labels.length > 3 ? labels.slice(0, 3) : labels;
const remainingLabels = labels.length > 3 ? labels.slice(3) : [];
return (
<div className="label-column">
{newLabels.map(
(label: string): JSX.Element => (
<TagWithToolTip key={label} label={label} color={color} value={value} />
),
)}
{remainingLabels.length > 0 && (
<Popover
getPopupContainer={popupContainer}
placement="bottomRight"
showArrow={false}
content={
<div>
{labels.map(
(label: string): JSX.Element => (
<TagWithToolTip
key={label}
label={label}
color={color}
value={value}
/>
),
)}
</div>
}
trigger="hover"
>
<Tag className="label-column--tag" color={color}>
+{remainingLabels.length}
</Tag>
</Popover>
)}
</div>
);
}
LabelColumn.defaultProps = {
value: {},
};
export default LabelColumn;

View File

@@ -0,0 +1,5 @@
export type LabelColumnProps = {
labels: string[];
color?: string;
value?: { [key: string]: string };
};

View File

@@ -0,0 +1,36 @@
import { Tag, Tooltip } from 'antd';
import { getLabelRenderingValue } from './utils';
function TagWithToolTip({
label,
value,
color,
}: TagWithToolTipProps): JSX.Element {
const tooltipTitle =
value && value[label] ? `${label}: ${value[label]}` : label;
return (
<div key={label}>
<Tooltip title={tooltipTitle}>
<Tag className="label-column--tag" color={color}>
{getLabelRenderingValue(label, value && value[label])}
</Tag>
</Tooltip>
</div>
);
}
type TagWithToolTipProps = {
label: string;
color?: string;
value?: {
[key: string]: string;
};
};
TagWithToolTip.defaultProps = {
value: undefined,
color: undefined,
};
export default TagWithToolTip;

View File

@@ -16,6 +16,28 @@ export const generatorResizeTableColumns = <T>({
};
});
export const getLabelRenderingValue = (
label: string,
value?: string,
): string => {
const maxLength = 20;
if (label.length > maxLength) {
return `${label.slice(0, maxLength)}...`;
}
if (value) {
const remainingSpace = maxLength - label.length;
let newValue = value;
if (value.length > remainingSpace) {
newValue = `${value.slice(0, remainingSpace)}...`;
}
return `${label}: ${newValue}`;
}
return label;
};
interface GeneratorResizeTableColumnsProp<T> {
baseColumnOptions: ColumnsType<T>;
dynamicColumnOption: { key: string; columnOption: ColumnType<T> }[];

View File

@@ -1,3 +1,4 @@
import { DownOutlined } from '@ant-design/icons';
import { Button, Dropdown } from 'antd';
import TimeItems, {
timePreferance,
@@ -33,7 +34,9 @@ function TimePreference({
return (
<TextContainer noButtonMargin>
<Dropdown menu={menu}>
<Button>{selectedTime.name}</Button>
<Button>
{selectedTime.name} <DownOutlined />
</Button>
</Dropdown>
</TextContainer>
);

Some files were not shown because too many files have changed in this diff Show More