Compare commits

..

235 Commits

Author SHA1 Message Date
Prashant Shahi
7c062163a1 chore(release): 📌 pin versions: SigNoz 0.41.1
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-03-15 02:24:09 +05:45
Prashant Shahi
0e2c699518 Merge branch 'main' into release/v0.41.1 2024-03-15 01:46:02 +05:30
Vikrant Gupta
c04d0e9419 Revert "Explorer Toolbar maximised and minimised (#4656)" (#4705)
This reverts commit aadb962b6c.

(cherry picked from commit cf22039562)
2024-03-15 01:57:03 +05:45
Prashant Shahi
d0feff00a7 Merge pull request #4690 from SigNoz/release/v0.41.0
Release/v0.41.0
2024-03-14 00:50:36 +05:30
Prashant Shahi
6c2a3d5d43 chore(signoz): 📌 pin versions: SigNoz 0.41.0, SigNoz OtelCollector 0.88.15
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-03-14 00:23:51 +05:45
Prashant Shahi
914b035b3f Merge branch 'main' into release/v0.41.0 2024-03-14 00:23:02 +05:45
SagarRajput-7
6b3af78873 Merge pull request #4689 from SagarRajput-7/billing-graph
feat: added isFetching condition and changed series color
2024-03-13 17:58:48 +05:30
Sagar Rajput
6adeef7e70 feat: added isFetching condition and changed series color 2024-03-13 17:50:17 +05:30
Rajat Dabade
44dc55c5ac FE: Design update for log context tab (#4601)
* refactor: initial setup for context view

* refactor: updated design for log context view

* refactor: updated comments and remove commented code

* refactor: updated comments

* refactor: handle hight issue

* refactor: initial setup for context view

* refactor: updated design for log context view

* refactor: updated comments and remove commented code

* refactor: updated comments

* refactor: handle hight issue

* refactor: added api version

* refactor: height set to parent height and remove unnessarry code

* refactor: removed commented code

---------

Co-authored-by: Yunus M <myounis.ar@live.com>
2024-03-13 17:37:48 +05:30
Srikanth Chekuri
3c419677e1 feat: add support for alerting on absent metric (#3245) 2024-03-13 17:37:32 +05:30
Rajat Dabade
aadb962b6c Explorer Toolbar maximised and minimised (#4656)
* refactor: done log explorer minimising save view toolbar

* refactor: local storage visibility support and done with traces toolbar

* refactor: added toolbar and removed commented code

* chore: css updates

* refactor: removed the background hightlighted code for droppable area

* refactor: merge conflict resolve and updated variable name
2024-03-13 17:28:09 +05:30
SagarRajput-7
c6080ca02e feat: [SIG-557]: added Billing usage graph - daily and weekly (#4686)
* feat: added Billing usage graph - daily and weekly

* feat: removed mocked response

* feat: removed weekly chart and fixed data transformations

* feat: added loading states

* feat: moved function to util file

* feat: fixed review comments

* feat: fixed JEST test case

* feat: test fix - commit

* feat: test fix - commit

* feat: test fix - commit

* feat: edited title conditionally

* feat: edited tooltip content

* feat: removed time from tooltip content and skeleton for cycleInfo Alert

---------

Co-authored-by: Sagar Rajput <sagarrajput@192.168.1.2>
2024-03-13 14:30:49 +05:30
Vishal Sharma
506448fe61 chore: dashboard info update (#4684) 2024-03-13 01:47:51 +05:30
Srikanth Chekuri
a42176599f chore: add day wise usage breakdown (#4648) 2024-03-12 22:45:31 +05:30
Srikanth Chekuri
adef0a4138 chore: add LogCommentEnricher middleware (#4681) 2024-03-12 18:39:28 +05:30
Srikanth Chekuri
c9816cce18 fix: use same time window as the logs/traces query (#4682) 2024-03-12 17:30:01 +05:30
Srikanth Chekuri
c6c2b9d809 chore: limit number of top level operations in services list (#4666) 2024-03-12 17:22:48 +05:30
Rajat Dabade
d9b379ae51 refactor: onblur convert to tag (#4662)
* refactor: onblur convert to tag

* refactor: on blur log body contains

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2024-03-12 14:34:10 +05:30
Rajat Dabade
dd2afe19f6 [Fix]: full view bar chart (#4667) 2024-03-12 14:22:27 +05:30
Rajat Dabade
0326a4d42a [Refactor]: Height for log explorer list panel (#4657)
* refactor: added fullview and fix height issue for logs

* refactor: hide full view button on full view mode

* refactor: removed fullview for logs

* refactor: remove max with for body
2024-03-12 12:20:45 +05:30
Srikanth Chekuri
b4d12966f3 fix: interpret missing point as zero value in formula evaluation (#4668) 2024-03-11 23:47:19 +05:30
Raj Kamal Singh
5a2d729ba9 Feat: qs autopopulate installed integration dashboards (#4680)
* chore: add test for dashboards for installed integrations

* feat: include dashboards for installed integrations in API response

* chore: add test expectation for getting installed integration dashboard by id

* feat: add support for retrieving installed integration dashboards by id

* chore: add dashboard id validation for integrations
2024-03-11 20:06:59 +05:30
Yunus M
666916fae2 fix: handle defaults for apm and aws (#4678) 2024-03-11 16:59:04 +05:30
Vishal Sharma
4b4008642d chore: extract dashboard/alert query info and send event (#4665)
* chore: extract dashboard/alert query info and send event

* chore: add totalDashboardsWithPanelAndName attribute in event
2024-03-11 16:45:06 +05:30
Srikanth Chekuri
7c2007faa3 fix: remove early return for services call in usage explorer (#4669) 2024-03-11 15:20:59 +05:30
Vikrant Gupta
6b87118fc6 feat: [SIG-546]: user with viewer roles can only view saved views (#4663)
* feat: [SIG-543]: Users with VIEWER access can create/edit/delete views for logs and traces

* feat: [SIG-543]: remove extra code

* feat: [SIG-543]: role changes in the save views toolbar

* feat: [SIG-543]: role changes in the save views toolbar

* feat: remove the save feature / dashboard / alert feature for viewer roles

* feat: remove the save feature / dashboard / alert feature for viewer roles

* fix: address review comments
2024-03-11 14:49:10 +05:30
Vikrant Gupta
49aba4fb1c feat: [SIG-543]: add time selection in the custom date selection (#4658)
* feat: [SIG-543]: inital commit

* feat: [SIG-543]: refactor date time modal to separate component

* feat: [SIG-543]: refactor date time modal to separate component

* feat: add back the time support according to the older designs in the date time picker

* fix: custom time picker minor UI fixes
2024-03-11 14:39:17 +05:30
Raj Kamal Singh
9ace374855 Feat: QS: Log Pipelines for installed integrations (#4674)
* chore: refactor: inject sqlx.DB into opamp.initDB instead of DB file name

* chore: reorganize test utils a little

* chore: add test validating pipelines for installed integrations show up in pipelines list

* chore: get basic integration pipelines testcase passing

* chore: reconcile experimental changes with latest state of develop

* chore: add integration test for reordering of pipelines

* chore: marker for integration pipelines using Id

* chore: hookup propagation of installed integration pipelines by opamp

* chore: add util for mapping slices

* chore: add support for reordering integration pipelines

* chore: exclude user saved integration pipelines if no longer installed

* chore: flesh out rest of intgeration pipelines scenarios

* chore: handle scenario when an integration is installed before any pipelines exist

* chore: notify agentConf of update after uninstalling an integration

* chore: some minor cleanup

* chore: some more cleanup

* chore: update ee server for changed controllers

* chore: some more cleanup

* chore: change builtin integration id prefix to avoid using colons that break yaml

* chore: update builtin integration id in test
2024-03-11 14:15:11 +05:30
Vikrant Gupta
a4d5774ae3 fix: update the md file for integrations config (#4677) 2024-03-11 11:48:36 +05:30
Nityananda Gohain
d0d10daa44 feat: support for timeshift in logs (#4607)
* feat: support for timeshift in logs

* fix: post process the timeshift function result

* fix: start and end times adjusted

* fix: only apply functions instead of entire post process

* fix: unnecessary error handling removed

* fix: apply functions for all sources

* feat: test added for timeshift

* fix: comments corrected

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2024-03-08 21:12:53 +05:30
Rajat Dabade
e519539468 Graph visibility state management. (#4632)
* refactor: change the state handling of graph visibility

* refactor: removed commented code
2024-03-08 14:11:38 +05:30
Vikrant Gupta
7051831539 fix: [SIG-542]: handle special characters in servicename (#4649)
* fix: [SIG-542]: handle special characters in servicename

* feat: handle . operator in the URL

* chore: left files to update
2024-03-08 00:08:12 +05:30
Raj Kamal Singh
c842e68288 chore: minor integrations UI cleanups (#4661) 2024-03-07 19:57:14 +05:30
Raj Kamal Singh
a295bf2fb6 Feat: QS: structure for built in integrations (#4655)
* feat: get builtin integrations started with nginx

* feat: get started with embedding and parsing of builtin integrations

* chore: add icons for nginx and redis integrations

* chore: stash current state of work

* chore: remove all yaml annotations since moved to JSON assets for bundled integrations

* chore: add file uri hydration in integration spec

* chore: refactor file uri hydration logic

* chore: add support for referencing JSON files with file uri

* chore: bring in initial integration assets

* chore: hookup builtin integrations and get all tests passing

* chore: update icons for postgres and mongo and some cleanup

* chore: some more cleanup

---------

Co-authored-by: Raj Singh <raj@Rajs-MacBook-Pro.local>
2024-03-07 19:26:20 +05:30
Vikrant Gupta
4cd40391c5 feat: route to the onboarding flow when clicking the sending logs in case of no logs (#4600)
* feat: refactor onboarding flow to add path params when selecting any module

* feat: added re-route to the onboarding flow in case of no logs and no traces

* chore: remove console logs

* chore: increase type safety

* chore: updated tab names

* chore: remove development conditions

* chore: handle cloud user

* feat: handle aws monitoring cases

* fix: apm framework not getting selected

* fix: apm framework not getting selected

* fix: apm framework not getting selected
2024-03-07 14:23:28 +05:30
Vikrant Gupta
7af4ba34af chore: [SIG-526]: Improve the light theme designs for integrations UI (#4659) 2024-03-07 14:12:06 +05:30
Rajat Dabade
54c69311ed Logs Strip color according to severity_text (#4643)
* refactor: initial setup

* refactor: done with setup

* refactor: done with severity text split color

* refactor: initial setup

* refactor: done with setup

* refactor: done with severity text split color

* chore: added unit test case

* refactor
: pointed to the correct variable

---------

Co-authored-by: Nityananda Gohain <nityanandagohain@gmail.com>
2024-03-07 12:25:00 +05:30
Vikrant Gupta
62af836554 fix: [SIG-549]: bring the ts config for pre-commit hook in sync with github CI (#4660)
* chore: dummy commit

* chore: dummy commit

* chore: dummy commit
2024-03-07 11:53:05 +05:30
Yunus M
f9b3ca01f9 feat: add clone query functionality (#4617)
* feat: add clone query functionality

* feat: update ui
2024-03-07 11:41:29 +05:30
Vikrant Gupta
0c4149225f feat: [SIG-526]: UI Integrations V0 (#4595)
* feat: integrations v0 base setup routes and components

* chore: typecheck fix

* feat: integrations landing page changes

* feat: initial header setup

* feat: integrations list page setup

* feat: integrations details content root setup

* feat: integration detail content setup

* feat: added overview tab

* feat: added data tab

* feat: handle configuration tab

* feat: add min height for the container

* feat: generate apis and hooks for usage

* feat: added remove integration modal

* feat: added remove integration modal

* feat: added remove integration modal

* feat: added test connection bars

* chore: add bottom margins

* feat: added test connection modal

* feat: add all types of test connection

* feat: add all types of test connection

* fix: address review comments

* fix: address review comments

* feat: added get all integrations API and search bar implemnetation

* feat: navigate to overview section in case of row click and configure in btn

* feat: integrate get integration details api

* feat: handle integration details page gracefully

* feat: integrate uninstall API and the connection states

* feat: add install integration API call

* feat: added api error handling

* feat: handle error states for list and details api

* feat: handle the logs and metrics columns

* feat: add TODOs for pending tasks

* feat: comment from side nav

* feat: added support for custom tags in react markdown

* chore: revert the temporary change for merge

* feat: integrate the status api calls and polling logic

* chore: add markdown components and correct the polling issue

* chore: handle light mode

* chore: remove integrations from sideNav

* fix: address review comments

* fix: address review comments
2024-03-06 22:25:02 +05:30
Raj Kamal Singh
7136ecc2fe chore: accept connection test lookback seconds as request param (#4650)
Also removes connectionStatus from integration details.
2024-03-06 11:06:04 +05:30
Vikrant Gupta
0c14145ef9 fix: [SIG-532]: Copy Log Link Functionality for new designs (#4644)
* fix: [SIG-532]: timeRange not updating correctly for copy log link

* fix: [SIG-532]: use virtuoso props to scroll to some intiial position rather than API hit

* fix: added styles for highlighted colors

* fix: handle colors for copy log link

* fix: update colors for copy log lines
2024-03-05 21:31:15 +05:30
Srikanth Chekuri
6618b47123 chore: bump github.com/SigNoz/prometheus to v1.9.79-0.1 (#4651) 2024-03-05 21:04:35 +05:30
Raj Kamal Singh
ab5285dee6 Feat: qs api integration connection status (#4628)
* chore: add integration attribs for connection tests and status

* chore: add connection status to integration details response

* chore: update integration lifecycle test to check for connection status too

* feat: add GetIntegrationConnectionTests to integrations manager and controller

* chore: add tests for querying integration connection status

* feat: add http API support for integration connection status

* chore: some cleanups

* chore: use PostableRule for integration alerts

* chore: some more cleanup
2024-03-05 15:23:56 +05:30
Vikrant Gupta
fdd7e022e9 fix: offset added hinders the timestamps for the traces (#4642)
* fix: offset added hinders the timestamps for the traces

* fix: offset added hinders the timestamps for the traces
2024-03-04 18:47:38 +05:30
Rajat Dabade
90d7f0200a FE: updated routes and modal for create alert css (#4602)
* refactor: updated routes and modal for create alert css

* refactor: button color changed

* refactor: redirect old routes to new routes
2024-03-04 17:42:17 +05:30
Vikrant Gupta
2713e186d3 fix: dashboard variables reset on tab visibility change (#4619) 2024-03-04 13:54:55 +05:30
Raj Kamal Singh
ffdb4cfff0 chore: update version for clickhouse mock dependency (#4640) 2024-03-04 12:00:05 +05:30
Srikanth Chekuri
b3b7522250 chore: update APM metrics to use v4 query range (#4638) 2024-03-04 10:15:43 +05:30
Raj Kamal Singh
0870030d1c Feat: qs integrations http api (#4622)
* chore: add http api test for signoz integrations

* chore: add controller for integrations

* chore: add http API handlers for integrations API

* chore: hook up integrations API in new servers

* chore: add remaining fields in Integration DTO

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2024-03-02 10:11:51 +05:30
Raj Kamal Singh
3fece44aef chore: update dependency github.com/srikanthccv/ClickHouse-go-mock from v0.4.0 -> v0.6.0 (#4637) 2024-03-01 15:55:15 +05:30
Yunus M
e5de35a769 fix: default version to v4 if version param not present in url params (#4636) 2024-03-01 15:37:55 +05:30
Yunus M
44ff1517d1 fix: update date picker styles (#4635) 2024-03-01 15:20:21 +05:30
Srikanth Chekuri
d77389abe3 feat: add support for email alert channel (#4599) 2024-03-01 15:05:28 +05:30
Yunus M
1a62a13aea chore: update query builder to support spatial aggregations and functions (#4569) 2024-03-01 14:51:50 +05:30
Rajat Dabade
97fdba0fae Update panel type on selecting new panel on dashboards. (#4634) 2024-03-01 13:04:53 +05:30
Nityananda Gohain
1aaafa4638 feat: use attribute if present for json query (#4458)
* feat: use attribute if present for json query

* fix: refractor test cases
2024-02-29 15:32:37 +05:30
Prashant Shahi
71c4fcc382 Merge pull request #4616 from SigNoz/release/v0.40.0
Release/v0.40.0
2024-02-28 19:46:06 +05:30
Prashant Shahi
9af1c2320b chore(signoz): 📌 pin versions: SigNoz 0.40.0, SigNoz OtelCollector 0.88.14
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-02-28 19:13:23 +05:45
Prashant Shahi
cdabf9060e Merge branch 'main' into release/v0.40.0 2024-02-28 19:11:34 +05:45
CheetoDa
4eb1948e4c feat: added aws monitoring section (#4614)
* feat: added aws monitoring section

* chore: fix lint issues

* chore: fix lint issues

* feat: handle redirect for aws monitoring

---------

Co-authored-by: Yunus M <myounis.ar@live.com>
2024-02-28 18:20:15 +05:30
Vishal Sharma
fe0ba5e3ba fix: create PAT not null error (#4613)
* fix: create PAT not null error
allow all admins to view all pats

* fix: allow revoking of token by all admin users
2024-02-28 17:37:30 +05:30
Srikanth Chekuri
8add13743a fix: remove unknown setting from connection string (#4612) 2024-02-28 15:06:47 +05:30
Rajat Dabade
9964e3425a Feat: Bar chart (#4562)
* feat: added bar panel and configuration for bar chart
2024-02-28 14:56:50 +05:30
Raj Kamal Singh
ddaa464d97 feat: QS package for integrations (#4578)
* chore: bring in latest state of QS api work for integrations

* chore: integrations v0 qs API: refactor installed integration struct

* chore: finish up with integration lifecycle tests

* chore: some cleanup

* chore: some more cleanup

* chore: some more cleanup

* chore: some more cleanup

* chore: some more cleanup

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2024-02-28 09:54:50 +05:30
Hayden
8f9d643923 Add basic support for secure clickhouse connections (#4178) 2024-02-27 23:41:00 +05:30
Prashant Shahi
d9ab100da3 ci(telemetry): include environment variables for ee build (#4603)
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-02-27 17:15:23 +05:30
Yunus M
7d32c63398 feat: frontend telemetry setup (#4560) 2024-02-27 16:40:29 +05:30
Yunus M
89c6eba913 feat: update naming to API keys to Access Tokens (#4597)
* feat: update naming to API keys to Access Tokens

* feat: update api-keys route to access-tokens
2024-02-27 13:38:43 +05:30
Vikrant Gupta
c38247abe4 fix: [SIG-528]: precommit typescript check for md files (#4596) 2024-02-26 18:17:34 +05:30
Yunus M
f9eddc9b18 fix: update no logs text and link based on the datasource (#4594) 2024-02-26 12:09:31 +05:30
Yunus M
17de5836bd feat: send only required details in billingevents (#4587) 2024-02-23 22:53:09 +05:30
Vikrant Gupta
fe37a2e7e0 fix: traceID link not opening from log details page (#4590) 2024-02-23 22:19:45 +05:30
Yunus M
f2d5d21581 fix: redirect old logs routes to new routes (#4584) 2024-02-22 16:57:06 +05:30
Vikrant Gupta
f3bc1a8f8a fix: date time value initialising to start of day in case of typing (#4585) 2024-02-22 16:32:30 +05:30
Prashant Shahi
f069ecdb76 Merge pull request #4582 from SigNoz/release/v0.39.1
Release/v0.39.1
2024-02-21 17:53:50 +05:30
Prashant Shahi
493aef0241 chore(signoz): 📌 pin versions: SigNoz 0.39.1, SigNoz OtelCollector 0.88.13
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-02-21 16:22:48 +05:45
Yunus M
7bca847f11 fix: show expired token label (#4581)
* fix: show expired token label

* fix: handle no expiry

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2024-02-21 15:38:18 +05:30
Vishal Sharma
0cb60e1c10 chore: update heartbeat, language event and add serviceName event (#4571)
* chore: update heartbeat, language event and add serviceName event

* chore: update tagsInfo
2024-02-21 14:49:33 +05:30
Rajat Dabade
ecd5ce92c2 List View for Dashboard (#4517)
* refactor: initial setup for list view logs

* feat: done with basic functionality panel view logs

* feat: added panel view

* fix: discard and edit issue

* refactor: removed not required params from uselogdata

* feat: trace list view

* fix: loader

* refactor: traces table component css update

* refactor: added open san font and udpated css

* fix: full view traces issue and search column css update

* refactor: remove consoles

* refactor: removed commented code and updated logic

* chore: build failure

* refactor: icons change for apdd panels

* refactor: rebased to develop

* refactor: added support for light mode

* refactor: fix tsc

* fix: query select issue

* chore: table column to lower case

* refactor: updated styling for both log and traces tables

* chore: removed comment code

* chore: remove the resizable block from table header traces

* refactor: log table header and body stayling updated

* fix: query range on every column add

* refactor: styling updates

* fix: query range log respect global time

* refactor: css update log table header

* refactor: removed unnecessary code

* refactor: log query range respect globaltime

* refactor: dropdown support to qb

* refactor: remove creating alert for list view

* refactor: fix the height of column select dropdown

* fix: dropdown suggestion for orderby

* refactor: remove the commented code

* refactor: full view respect global time

* refactor: css updates

* refactor: should fire query range on variable change

* refactor: css updates for log list view

* refactor: removed the unused changes

* refactor: handle error state for exploere columns

* refactor: handle error state for explorer columns

* chore: generate yarn lock file

* refactor: pagination for order by timestamp

* fix: full text body contain issue

* refactor: inverted the operator for next and previous button config

* refactor: rename variable handle light mode

* fix: no log issue

* chore: renamed variables

---------

Co-authored-by: Vikrant Gupta <vikrant.thomso@gmail.com>
2024-02-20 16:21:07 +05:30
Srikanth Chekuri
aa67b47053 fix: address gaps in alert to notification link (#4573) 2024-02-20 10:42:30 +05:30
Yunus M
e2669eb370 API ingestion keys - CRUD (#4524)
* feat: api keys crud - integration v0.1

* feat: add test cases

* fix: add review comments

* feat: api integration and ui updates

* feat: update test cases

* feat: update expiriesAt request payload

* feat: ui feedback updates

* feat: api keys crud - integration v0.1

* feat: add test cases

* fix: add review comments

* feat: api integration and ui updates

* feat: update test cases

* feat: update expiriesAt request payload

* feat: ui feedback updates

* feat: handle light mode styles

* feat: hide pagination on single page

* feat: do not show last used if not present or 0

* feat: show tooltip on role

---------

Co-authored-by: Rajat Dabade <rajat@signoz.io>
2024-02-19 09:19:06 +05:30
Srikanth Chekuri
c4bbbf372c fix: change the order of local and distributed table (#4565) 2024-02-17 22:05:33 +05:30
Yunus M
0c59953cb5 feat: open left nav items in new tab on cmd ctrl click (#4561) 2024-02-17 14:59:49 +05:30
Vikrant Gupta
b10f17de78 chore: Added jest cases for logs explorer page (#4553)
* chore: base file for logs explorer jest test cases

* chore: added base setup for logs explorer jest fixing the uplot/d3-interpolate/antd-config errors

* chore: added test for rendering of logs explorer page without API calls

* chore: added test for rendering of logs with API call

* chore: used virutoso mock to render items on the screen

* chore: used virutoso mock to render items on the screen

* chore: update dummy data
2024-02-16 18:22:33 +05:30
Ankit Nayan
bbf9787fb3 merging main 2024-02-16 14:13:37 +05:30
Vishal Sharma
d11c1eb439 feat: api management (#4557)
* feat: api management

* chore: address review comments and typos

* chore: add sort and created by user object on create

* chore: replace expiresAt with expiresInDays for request body
2024-02-16 12:46:33 +05:30
Vikrant Gupta
548c531956 fix: dashboard panel light theme (#4556)
* fix: dashboard panel light theme

* fix: logs pipeline page crashing on opening context for stimulated logs

* fix: logs pipeline page crashing on opening context for stimulated logs
2024-02-15 16:25:55 +05:30
Yunus M
4e75479831 feat: ui updates - traces explorer (#4555) 2024-02-15 14:38:21 +05:30
Vikrant Gupta
633b551e5d fix: qb search not respecting the saved views panel type (#4554) 2024-02-15 14:13:05 +05:30
Srikanth Chekuri
f734142419 chore: add ExponentialHistogram support for metrics v4 query range (#4525) 2024-02-14 23:33:19 +05:30
Yunus M
aa9a3e9349 fix: remove duplicate settings tab (#4552) 2024-02-14 22:50:18 +05:30
Yunus M
ab950135ff fix: disable cloud features for oss (#4551) 2024-02-14 22:00:17 +05:30
Prashant Shahi
b4e0e89b05 Merge pull request #4549 from SigNoz/release/v0.39.0
Release/v0.39.0
2024-02-14 18:23:52 +05:30
Prashant Shahi
12a33960ff chore: update go.mod
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-02-14 18:27:30 +05:45
Prashant Shahi
65ed0c0c05 chore(signoz): 📌 pin versions: SigNoz 0.39, SigNoz OtelCollector 0.88.12
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-02-14 18:17:28 +05:45
Prashant Shahi
6eb7693294 Merge branch 'main' into release/v0.39.0 2024-02-14 18:15:20 +05:45
Yunus M
7ec25b4f62 fix: invalid custom time value (#4547) 2024-02-14 17:26:33 +05:30
Vikrant Gupta
b3bc78d23c fix: date time value retain on location switch (#4546)
* fix: date time value retain on location switch

* chore: added inline comments

* feat: added shortcut strings based on user os

* feat: added shortcut strings based on user os

* feat: added shortcut strings based on user os
2024-02-14 16:47:39 +05:30
Yunus M
bd4786f128 feat: add borders to keyboard shortcut and settings tables (#4545) 2024-02-14 15:27:01 +05:30
Vikrant Gupta
81241170e5 feat: support zoom in for bar chart logs explorer (#4542)
* feat: support zoom in for bar chart logs explorer

* feat: add back navigation support for bar chart zoom in
2024-02-14 15:18:04 +05:30
Vikrant Gupta
e0df371a8d fix: added missing updated time on first load for back navigation (#4544)
* fix: added missing updated time on first load for back navigation

* fix: cleanup console
2024-02-14 14:00:17 +05:30
Vikrant Gupta
cfea51d9ee fix: relative time preferences not respected (#4543) 2024-02-14 12:56:54 +05:30
Vikrant Gupta
037f5ae4c8 feat: added focus for qb search for last search bar (#4534) 2024-02-14 12:49:24 +05:30
Yunus M
d6b7587bbe feat: show retention info for cloud users and show count next to team… (#4536)
* feat: show retention info for cloud users and show count next to team members and pending invites

* feat: add safety check for saved views response
2024-02-14 12:42:36 +05:30
Vikrant Gupta
0dffd86287 fix: number attributes not showing up in raw view (#4541) 2024-02-14 12:22:12 +05:30
Nityananda Gohain
c75a44c620 fix: orderby not working for attributes fixed (#4540) 2024-02-14 10:49:31 +05:30
Ankit Nayan
cbf3041dde Update Saved Views mutation to require Editor access(#4538) 2024-02-13 21:50:52 +05:30
Rajat Dabade
d0b43f3802 fix: button border color for tab in log explorer (#4535) 2024-02-13 19:18:00 +05:30
CheetoDa
1ee672c020 feat: onboarding flows for rust swift and elixir (#4507)
* feat: onboarding flows for rust swift and elixir

* fix: fixed some issues

* fix: spellcheck done

* fix: feedback incorporated

* chore: fixed swift docs

* chore: minor fixes

* fix: lint errors

---------

Co-authored-by: Yunus M <myounis.ar@live.com>
2024-02-13 16:52:28 +05:30
Rajat Dabade
ad8924ed13 [Refactor]: added extra param to check isdepend on query build (#4523)
* refactor: added extra param to check isdepend on query build

* refactor: added extra param to check isdepend on query build

* refactor: updated enabled query condition

* refactor: added extra param to check isdepend on query build

* refactor: updated enabled query condition

* chore: clean code
2024-02-13 15:19:15 +05:30
Vikrant Gupta
cff0e1cf1e fix: old and new dashboards in sync with local storage (#4520)
* fix: old and new dashboards in sync with local storage

* fix: remove code

* fix: remove console log

* fix: remove console log
2024-02-13 13:57:24 +05:30
Vikrant Gupta
02f83e4b4a fix: shortcuts break when there are multiple queries (#4532) 2024-02-13 01:40:11 +05:30
Rajat Dabade
6bc5ceac3e [Fix]: delete formula issue (#4526) 2024-02-12 21:42:56 +05:30
Vikrant Gupta
3a20862d0c feat: added shortcuts page in the side nav (#4506)
* feat: added shortcuts page in the side nav

* fix: update shortcuts for add to dashboard and alerts

* fix: cmd+enter should stage and run query

* chore: refactor the shortcuts utils

* feat: support run query even when input is focussed

* fix: dropdown visibility change

* feat: add shortcuts for sideNav

* feat: auto focus logs explorer search bar with hotkey

* fix: update the shortcuts for sideNav and dependencies

* fix: remove dashboard and alert shortcuts

* fix: minor typo changes
2024-02-12 19:53:35 +05:30
Nityananda Gohain
0e331dd177 feat: support cache in logs (#4516)
* feat: support cache in logs

* fix: revert fluxinterval changes

* feat: support for limit queries

* feat: support for formula

* fix: refractor code and don't return all points

* fix: add nil params check

* fix: error handling updated

* fix: start and end params fix
2024-02-12 18:45:21 +05:30
Yunus M
ab4f6adb19 Logs explorer design update (#4352)
* feat: logs explorer - new design

* feat: update styles

* feat: added new toolbar for logs explorer (#4336)

* feat: logs list view changes (#4348)

* feat: logs list view changes

* fix: list view and toolbar styles

* feat: side btns

* feat: added auto refresh handler

* feat: handle popover close for btn click date time

* feat: extract the common log actions btn component

* feat: update the button for log line actions

* fix: event propagation from context button

* feat: use styles from ui-library

* Query builder design update (#4359)

* feat: QB design update

* fix: add functionality and light mode styles

* fix: ts issues

* fix: update all css color variables to correct names

* fix: lint errors

* feat: new table view for logs explorer list section  (#4353)

* feat: table view changes for logs list

* feat: code refactor to support log line actions

* feat: code refactor to support log line actions

* fix: the positioning of the btns

* feat: fix the table onclick

* fix: header issue

* fix: on hover

* fix: type issue

* fix: eslint error

* fix: type errors (#4360)

* feat: handle light theme for logs explorer design changes (#4363)

* feat: handle light theme for list tables and dateTime selection

* feat: handle light theme for popover

* fix: address review comments

* feat: date time custom time modal to render inside the new popover (#4366)

* feat: single calender for range picker

* fix: edgecases

* feat: integrate date time selector across app

* fix: remove dangling border after element removal

* feat: handle qb design changes across the application

* feat: handle light theme

* feat: handle light theme

* fix: virtuoso scroll refresh issue

* feat: handle new typing changes for date time picker v2 (#4386)

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

* chore: styles improvement across new design (#4389)

* fix: improve date time styles

* feat: table view changes according to new design

* fix: button visibility in clickhouse and promQL headers (#4390)

* feat: change the tabs to new design buttons for query builder

* Settings theme change (#4368)

* feat: settings theme change

* [Refactor]: New design for Log details page (#4362)

New design for Log details page 

Co-authored-by: Vikrant Gupta <vikrant.thomso@gmail.com>
Co-authored-by: Yunus M <myounis.ar@live.com>

* feat: save view for new design (#4392)

* feat: save view for new design

* refactor: done with save view

* feat: update styles for logs detail view (#4407)

* feat: update styles for logs detail view

* feat: update styles for logs detail view

* feat: add raw view attributes in the logs list view (#4422)

* feat: add raw view attributes in the logs list view

* feat: add raw view attributes in the logs list view

* fix: raw attributes

* fix: logs UI improvements (#4426)

* fix: remove fixed times from the date time picker v2

* fix: added old logs explorer CTA in new designs

* feat: handle active logs indicator update

* fix: address review comments

* fix: old logs explorer page

* fix: remove info text and add relative time buttons

* fix: update logs explorer tab designs

* fix: update logs explorer tab designs

* fix: update logs explorer tab designs

* refactor: New design for Save views. (#4435)

* feat: [GH-4436]: date range enhancements (#4448)

* feat: [GH-4436]: when selecting custom time range it should be from start of day to end of date

* fix: custom time width and refresh text visibility issues (#4428)

---------

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

* feat: update ui (#4449)

* feat: added loading and error states for logs design (#4452)

* feat: added loading and error states for logs design

* feat: added error states for table view and time series view

* feat: handle error and loading states

* feat: loading states

* [Refactor]: Tab Switch deplay issue and UI improvement for Clickhouse (#4409)

* fix: switching between logs display tabs (#4457)

* [Feat]: View in Traces (#4450)

* refactor: datetime selector beside run query removed add to dashboard

* refactor: added tab for traces view details page

* refactor: done with the save view in traces

* fix: the gittery effect when navigatigating from views

* refactor: view tab view title light mode support

* refactor: removed console

* fix: gittery effect when switch view from views tabs

* refactor: separate traces routes

* refactor: remove query params

* chore: fix tsc issues

* fix: jest config issues

* fix: update TODO and remove extra braces

* feat: handle loading states and incorporate ui feedback (#4479)

* UI feedback updates (#4482)

* feat: handle loading and fix ui issues

* feat: ui updates

* fix: logs explorer issues (#4483)

* fix: logs explorer issues

* fix: jest test cases

* feat: support custom times unique to pages new design changes (#4485)

* fix: loading states for list log view (#4486)

* fix: logs search view query fix, logs details view - attribute tags alignment fix (#4489)

* fix: delete empty file

* fix: chart loading when scrolling logs (#4495)

* fix: chart should not load when scrolling the logs as it is already fetched

* fix: make the search bar as default rather than advanced options

* fix: rename show context to show in context

* fix: query range api not triggering on default select first load (#4498)

* Refactor: Log Explorer UI changes.  (#4502)

* refactor: used selected view enum

* refactor: updated hight of switch old button and tab border

* refactor: import fixes

* refactor: query builder border and button groups

* refactor: removed hypen from refreshed

* refactor: show delete button only when there is more than one query

* refactor: sqaure up the query build button groups

* refactor: updated css

* fix: additional filter color button shadow

* refactor: removed commented code and used selected panel enum

* refactor: updated typecheck script

* refactor: used enum selected view (#4504)

* fix: retain the current query on date time change (#4510)

* feat: added new icon for promQL and added tooltips for dashboards and alerts (#4512)

* feat: added new icon for promQL and added tooltips for dashboards and alerts

* fix: styles at 1440 px zoom

* fix: rename clickhouse to clickHouse

---------

Co-authored-by: Vikrant Gupta <54737045+Vikrant2520@users.noreply.github.com>
Co-authored-by: Vikrant Gupta <vikrant.thomso@gmail.com>
Co-authored-by: Rajat Dabade <rajat@signoz.io>
2024-02-12 00:23:19 +05:30
Vikrant Gupta
50834be4db fix: update the extend trial from default mailto client to notification panel (#4514) 2024-02-11 23:55:54 +05:30
Srikanth Chekuri
260d21afd0 fix: update prom rule to use range query (#4461) 2024-02-11 22:31:46 +05:30
Srikanth Chekuri
3b98073ad4 chore: add time shift function and some refactoring (#4445) 2024-02-11 00:31:47 +05:30
Liran Tal
6bd2c1ba74 docs: use the proper Node.js written convention form (#3140) 2024-02-10 17:05:29 +05:30
Lars Lehtonen
968cc0eb82 chore: fix dropped errors in tests
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2024-02-10 15:56:54 +05:30
Ankit Nayan
3ce385ef23 fix: ee/query-service/Dockerfile to reduce vulnerabilities (#4443)
The following vulnerabilities are fixed with an upgrade:
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6152404
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6152404
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6160000
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6160000
- https://snyk.io/vuln/SNYK-ALPINE318-OPENSSL-6191692

Co-authored-by: snyk-bot <snyk-bot@snyk.io>
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2024-02-10 15:48:22 +05:30
Srikanth Chekuri
c6581782d0 chore: add formula eval in query-service (#4402) 2024-02-06 22:29:12 +05:30
Srikanth Chekuri
61977ebe86 chore: bump clickhouse-server to 24.1.2-alpine (#4492)
Co-authored-by: Prashant Shahi <prashant@signoz.io>
2024-02-06 18:53:50 +05:30
Prashant Shahi
56b71d0f02 ci(testing-deploy): update workflow to handle force-push scenerio (#4503)
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-02-06 16:49:23 +05:30
Vikrant Gupta
f6ab060545 feat: setup the context for keyboard hotkeys (#4493)
* feat: setup the context for keyboard hotkeys

* feat: add error handling for duplicate callbacks

* feat: supported added for caps and document the return value

* feat: added shortcut for cmd+b for sideNav open and close

* feat: added jest test

* fix: address review comments

* fix: block the browser default actions wherever possible

* fix: remove browser ovverides prevention code
2024-02-06 14:17:27 +05:30
Nityananda Gohain
554c4332c4 fix: don't throw error while fetching orgname (#4496)
* fix: don't throw error while fetching orgname

* fix: don't ignore the error
2024-02-05 20:23:20 +05:30
Prashant Shahi
9d689693b4 chore(gh-workflows): 💚 bump up GH action versions (#3702)
* chore(gh-workflows): 💚 bump up GH action versions

* ci(e2e-k3s): fix the test environment

* chore: upgrade checkout/setup-node to v4

* chore: upgrade appleboy/ssh-action to v1.0.3

---------

Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-02-05 14:46:06 +05:30
Vikrant Gupta
26bc94fc46 feat: support dashboard local state (#4475) 2024-02-05 12:07:55 +05:30
Nityananda Gohain
6837c41090 fix: remove sending_queue and retry_on_failure settings (#3815)
Co-authored-by: Prashant Shahi <prashant@signoz.io>
2024-02-05 11:26:45 +05:30
Srikanth Chekuri
8fe0e60208 fix: make label compliant with prometheus spec (#4488) 2024-02-03 06:31:10 +05:30
Srikanth Chekuri
00b111fbe3 feat: add alerts to explorer link in notification (#4446) 2024-02-02 21:16:14 +05:30
Prashant Shahi
0bebd3e338 Merge pull request #4487 from SigNoz/release/v0.38.2
Release/v0.38.2
2024-02-02 17:59:34 +05:30
Prashant Shahi
d5e0a26f55 chore(signoz): 📌 pin versions: SigNoz OtelCollector 0.88.11
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-02-02 17:58:55 +05:45
Prashant Shahi
48ebe91713 chore(signoz): 📌 pin versions: SigNoz 0.38.2
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-02-02 17:44:59 +05:45
Prashant Shahi
5bc3c074f8 Merge branch 'main' into release/v0.38.2 2024-02-02 17:44:16 +05:45
Yunus M
f5b5a9a657 fix: maintain existing pagination configs (#4484)
* fix: maintain existing pagination configs

* fix: pass pagination info services table

* fix: general setting - cloud - add email mailto link
2024-02-02 16:44:27 +05:30
Vikrant Gupta
ac835c80e9 fix: custom range should be unique to pages (#4460)
* fix: custom range should be unique to pages

* fix: added type safety

* fix: added type safety
2024-02-02 14:43:59 +05:30
Vikrant Gupta
2cf0bb4fa5 feat: add typecheck on pre-commit hook (#4472)
* feat: add typecheck on pre-commit hook
2024-02-02 12:58:14 +05:30
Yunus M
0f44246795 feat: all line series with same labels should have same color in a dashboard (#4478) 2024-02-01 18:06:32 +05:30
Yunus M
64307f323f feat: show info message in general settings for cloud users to reachout for retention change (#4476) 2024-02-01 04:04:19 +05:30
Srikanth Chekuri
616b8e0a45 Merge pull request #4474 from SigNoz/release/v0.38.1
Release v0.38.1
2024-02-01 01:07:16 +05:30
Srikanth Chekuri
2c0690a8ee chore: bump version to 0.38.1 2024-02-01 00:55:56 +05:30
Ankit Nayan
2f361de693 merging main 2024-02-01 00:50:21 +05:30
Yunus M
457380c065 Revert "fix: Logs UI: querybuildersearch: avoid emptying out query on sourceK…" (#4473)
This reverts commit 085cf34a49.
2024-02-01 00:13:42 +05:30
Prashant Shahi
96e3d00e74 Merge pull request #4469 from SigNoz/release/v0.38.0
Release/v0.38.0
2024-01-31 18:28:11 +05:30
Prashant Shahi
d224e08145 Merge branch 'main' into release/v0.38.0 2024-01-31 17:34:02 +05:45
Prashant Shahi
13ced00a35 chore(signoz): 📌 pin versions: SigNoz 0.38, SigNoz OtelCollector 0.88.9
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-01-31 17:27:41 +05:45
Yunus M
5c60a862e5 fix: update only showTotal property by spreading pagination object (#4467)
* fix: update only showTotal property by spreading pagination object
2024-01-31 15:59:40 +05:30
Yunus M
78c9330666 fix: set light bg for full screen in dashboard (#4465) 2024-01-31 14:25:27 +05:30
Vikrant Gupta
01fc7a7fd4 fix: [GH-4451]: custom time range modal closed on focussing closed date (#4456)
* fix: [GH-4451]: custom time range modal closed on focussing closed date

* fix: jest test
2024-01-30 18:50:02 +05:30
Yunus M
0200fb3a21 fix: close delete modal on delete success (#4459) 2024-01-30 16:47:58 +05:30
Yunus M
e977963763 feat: show total items count in table (#4453) 2024-01-29 18:21:51 +05:30
Yunus M
824d9aaf85 feat: users should choose either to broadcast all or enter specific channels to alert (#4441)
* feat: users should choose either to broadcast all or enter specific channels to alert

* fix: remove console logs
2024-01-29 11:12:41 +05:30
Srikanth Chekuri
4db3e5e542 chore: include status (#4447) 2024-01-29 00:42:19 +05:30
Yunus M
a8b293a510 fix: variable selection flow - dependent variable option not updated … (#4438)
* fix: variable selection flow - dependent variable option not updated on change

* fix: dropdown width and parent element update

* fix: add key to variable item inputs
2024-01-27 12:59:28 +05:30
Srikanth Chekuri
4a4f48cec8 chore: support p9{9,5,0},75,50 for space aggregation (#4382) 2024-01-26 17:07:23 +05:30
Vikrant Gupta
7e5cf65ea3 fix: [GH-4434]: dashboard variables performance issues (#4437) 2024-01-25 23:12:19 +05:30
Keshav Gupta
bb7417ffbd fix:edit the nameon sign up page if name is blank (#4216)
Co-authored-by: keshav <keshav.gupta@jarvis.consulting>
2024-01-25 19:42:14 +05:30
Raj Kamal Singh
085cf34a49 fix: Logs UI: querybuildersearch: avoid emptying out query on sourceKeys update if tags are yet to be populated (#4355)
* fix: querybuildersearch: do not call query onChange from sourceKeys useEffect if tags is empty

* chore: add comment explaining change
2024-01-25 12:35:36 +05:30
Srikanth Chekuri
be27a92fc9 chore: add functions support (#4381) 2024-01-25 01:14:45 +05:30
Vikrant Gupta
253137a6b8 fix: center align the dashboard delete modal (#4429) 2024-01-25 01:05:47 +05:30
Prashanth Banda
fce7ab7d24 fix(frontend,serviceMap): dynamically truncate service map node label (#4365) 2024-01-25 00:47:09 +05:30
Prashant Shahi
71f6b355c4 Merge pull request #4430 from SigNoz/release/v0.37.2
Release/v0.37.2
2024-01-24 23:19:16 +05:30
Prashant Shahi
110b545454 chore(signoz): 📌 pin versions: SigNoz 0.37.2, SigNoz OtelCollector 0.88.9
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-01-24 23:15:12 +05:45
Yunus M
5b0e3d375a fix: custom time width and refresh text visibility issues (#4428) 2024-01-24 16:09:32 +05:30
Rajat Dabade
9e05cb48fe refactor: fill span for full view and dashboard view (#4424)
* refactor: fill span for full view and dashboard view

* refactor: fill span works in full view and dashboard
2024-01-24 15:37:34 +05:30
Yunus M
6d67ca72a0 fix: update search logic in dashboard to search for title, description, tags (#4427) 2024-01-24 14:18:15 +05:30
Vikrant Gupta
0626081eee feat: added log attributes in the raw view old designs (#4423)
* feat: added log attributes in the raw view old designs

* feat: support it in old explorer page
2024-01-24 11:32:48 +05:30
Rajat Dabade
199d52b39f refactor: added null check while searching for dashboard (#4421)
* refactor: added null check while searching for dashboard

* refactor: flitering null value out

* chore: removed extra space

* refactor: remove unnecessary null check
2024-01-23 16:36:25 +05:30
Ankit Nayan
204cad8448 merging main 2024-01-22 23:45:18 +05:30
Yunus M
8c6096d60e fix: reset env on data source select, set logo center aligned (#4417) 2024-01-22 21:47:55 +05:30
Prashant Shahi
9de9fb5863 Merge pull request #4413 from SigNoz/release/v0.37.1
Release/v0.37.1
2024-01-22 19:54:11 +05:30
Prashant Shahi
64d854ffa2 chore(signoz): 📌 pin versions: SigNoz 0.37.1
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-01-22 19:55:04 +05:45
Prashant Shahi
6b073280a4 Merge branch 'main' into release/v0.37.1 2024-01-22 19:54:38 +05:45
Vikrant Gupta
79e6699b37 fix: logs page crash when special chars present in the value of query (#4408) 2024-01-22 19:06:33 +05:30
Rajat Dabade
d563778479 [Fix]: Resolve glitch in graph due to variable and time stamp change (#4406)
* refactor: resolve glitch in variable and time stamp change

* refactor: removed unwanted code

* refactor: updated code
2024-01-22 16:36:03 +05:30
Vikrant Gupta
255b3dd3b0 fix: back btn navigation on first load (#4405)
* fix: back btn navigation on first load

* fix: remove console logs

* chore: refactor the logic to a function and added code comments
2024-01-22 14:47:25 +05:30
Vikrant Gupta
00e97fa401 fix: trial banner moving to left screen and breaking trace detail page (#4403)
* fix: trial banner moving to left screen and breaking trace detail page

* fix: trial banner moving to left screen and breaking trace detail page
2024-01-22 13:12:02 +05:30
Prashant Shahi
9755ba6b47 Merge pull request #4400 from SigNoz/release/v0.37.0
Release/v0.37.0
2024-01-20 02:03:04 +05:30
Nityananda Gohain
f3fdd2dd6c chore: add tenantId and orgName in usage (#4399)
* feat: add tenantId and orgName in usage

* fix: update regex

* fix: if else logic updated
2024-01-20 01:24:09 +05:30
Prashant Shahi
d4248fe933 chore(signoz): 📌 pin versions: SigNoz 0.37.0, SigNoz OtelCollector 0.88.8
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2024-01-20 00:19:42 +05:45
Vishal Sharma
a8d70206ab chore: update onboarding events (#4387)
* chore: update onboarding events

* chore: update retry count
2024-01-19 17:32:52 +05:30
Yunus M
7b344f7a75 Revert "fix: update time stamp on the first load in URL to help with back navigation" (#4398) 2024-01-19 17:01:52 +05:30
Vikrant Gupta
f0669a6dc1 fix: update time stamp on the first load in URL to help with back navigation (#4397)
* fix: update time stamp on the first load in URL to help with back navigation
2024-01-19 13:52:14 +05:30
Rajat Dabade
4a7d972c85 refactor: conditional based apdex on metrics and trace query range (#4395)
* refactor: conditional based apdex on metrics and trace query range

* chore: add invalid float conversion

* Revert "refactor: conditional based apdex on metrics and trace query range"

This reverts commit ca44a7aedd.

* refactor: added servicename to the query params

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2024-01-19 13:50:51 +05:30
Rajat Dabade
51c1f88593 Revert "[Feat]: added iscolumn in option rendering" (#4396) 2024-01-19 12:05:44 +05:30
Yunus M
c1b9049176 fix: allow workspace blocked users to extend trial (#4393)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2024-01-19 11:11:29 +05:30
Rajat Dabade
46559014f7 [feat]: persistence of graph toggle on variable change (#4316)
* feat: persistence of graph toggle on variable change

* fix: reverted the previous changes

* chore: full view global time selector to right
2024-01-18 23:22:30 +05:30
Srikanth Chekuri
0c1a500142 chore: update onboarding docs to send logs from the end with a note for about beginning (#4374) 2024-01-18 20:02:25 +05:30
Vikrant Gupta
26d6a869c6 fix: button visibility in clickhouse and promQL headers (#4390) 2024-01-18 16:44:52 +05:30
Vikrant Gupta
f99da73098 fix: [GH-4383]: handle special characters in the services name (#4388)
* fix: [GH-4383]: handle special characters in the services name
2024-01-18 15:01:32 +05:30
Yunus M
4a1c48b72b fix: autosave layout to layout change (#4385)
* fix: autosave layout to layout change

* fix: autosave layout to layout change

* refactor: no update api call on opening dashboard

* refactor: removed extra put api call

* refactor: if condition changed

---------

Co-authored-by: Rajat-Dabade <rajat@signoz.io>
2024-01-18 15:01:10 +05:30
Rajat Dabade
1163c16506 [Feat]: added iscolumn in option rendering (#4334)
* feat: added iscolumn in option rendering

* chore: build failure

* fix: build failure
2024-01-18 14:14:10 +05:30
Vikrant Gupta
bb558dde8e Merge pull request #4380 from SigNoz/GH-4325
feat: [GH-4325]: update the URL time query params when zoom in and zoom out of charts
2024-01-17 18:15:47 +05:30
Vikrant Gupta
e89c000252 Merge branch 'develop' into GH-4325 2024-01-17 18:09:03 +05:30
Rajat Dabade
4e8e7745c1 [FE]: spaces in legend formatting (#4349)
* refactor: spaces in legend formatting

* refactor: spaces in legend formatting

* chore: string to const string

* refactor: replace string by const
2024-01-17 15:17:51 +05:30
Vikrant Gupta
512fcda33d fix: address review comments 2024-01-17 14:04:38 +05:30
Vikrant Gupta
6f43b085b0 Merge branch 'develop' into GH-4325 2024-01-17 13:57:25 +05:30
Vikrant Gupta
54038b8ddf feat: handle back btn changes 2024-01-17 13:57:05 +05:30
Yunus M
00c9ef50de fix: set max 6 months for user entered time (#4384)
* fix: set max 6 months for user entered time

* fix: set max 6 months for user entered time
2024-01-17 13:01:55 +05:30
Vikrant Gupta
52750e5248 Merge branch 'develop' into GH-4325 2024-01-16 17:40:28 +05:30
Vikrant Gupta
cbce1b1847 feat: [GH-4325]: update the URL time query params when zoom in and zoom out of charts 2024-01-16 17:35:07 +05:30
Srikanth Chekuri
abaf6126e5 chore: add /v4/query_range endpoint (#4361) 2024-01-16 16:56:20 +05:30
Yunus M
739b1bf387 feat: custom date time value (#4367)
* feat: custom date time value

* fix: update custom date picker

* fix: old placeholder value flicker

* fix: html semantics and move styles to css

* fix: remove console logs

---------

Co-authored-by: Vikrant Gupta <vikrant.thomso@gmail.com>
2024-01-16 01:13:52 +05:30
Vikrant Gupta
cbf150ef7b fix: update correct format in URL in case of custom date time (#4371) 2024-01-15 18:46:18 +05:30
Rajat Dabade
c28f367f46 refactor: updated height for date selector (#4331) 2024-01-11 16:22:20 +05:30
Yunus M
1e679a0d64 fix: empty string search doesn't return all exceptions (#4346)
* fix: empty string search doesn't return all exceptions

* fix: add type
2024-01-10 14:07:23 +05:30
Rajat Dabade
6f5f361a7e fix: soft min and soft max undefined issue (#4351) 2024-01-10 13:12:31 +05:30
Raj Kamal Singh
d65d75ef69 Fix: FE: pipelines: should be able to exit edit mode without making a change (#4335)
* fix: show cancel button on entering edit mode before any changes have been made

* chore: align pipeline page save/cancel buttons to the right
2024-01-10 11:26:25 +05:30
Srikanth Chekuri
722a38491e chore: add signozspanmetrics delta temporality pipeline (#3776) 2024-01-10 01:16:24 +05:30
Srikanth Chekuri
361efd3b52 chore: add querier v2 (#4170) 2024-01-09 22:19:03 +05:30
Rajat Dabade
7b46f86f7f [Refactor]: resolve the wrong payload in timeseries log explorer issue (#4345)
Co-authored-by: Vikrant Gupta <54737045+Vikrant2520@users.noreply.github.com>
2024-01-09 17:47:23 +05:30
Rajat Dabade
5b39dc36d6 [Feat]: soft min and soft max in uplot chart (#4287)
* feat: soft min and soft max in uplot chart

* fix: build pipeline

* fix: tsc

* refactor: added test case

* refactor: updated logic and added unit test

* refactor: updated logic

* chore: removed placeholder

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
Co-authored-by: Yunus M <myounis.ar@live.com>
2024-01-09 14:19:23 +05:30
Keshav Gupta
5fe7948be9 feat: preserve the sorting searching and pagination in dashboard page (#4319)
* feat: preserved the sorting searching and pagination

* fix: filter in dashboard data
2024-01-09 13:26:44 +05:30
Yunus M
a47a90b0f3 fix: validate password on paste, change (#4344)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2024-01-09 12:55:24 +05:30
Srikanth Chekuri
be6bca3717 chore: add prepare query for cumulative/unspecified table (#4169) 2024-01-08 20:04:21 +05:30
Srikanth Chekuri
92717774a2 fix: throw error when response for value panel returns more than one series (#4332) 2024-01-08 18:11:22 +05:30
Srikanth Chekuri
e7fabca38e chore: fix the query range cache gaps (#4283) 2024-01-08 18:00:42 +05:30
Srikanth Chekuri
525dea343c chore: add prepare query for delta/unspecified table (#4168) 2024-01-08 01:33:04 +05:30
Yunus M
7d960b79dd feat: update sidebar and base theme styles (#4272)
* feat: update sidebar and base theme styles

* feat: update sidebar items and styles

* feat: wire up logs navigation and update user settings page

* feat: update styles to handle light mode, add full view header

* feat: update onboarding header and styles

* feat: remove unused routes

* feat: handle sidebar collapse

* feat: show pointer on logo hover

* feat: fix logs module navigations

* feat: update logo click route

* feat: update entity name color to primary in application and dashboard tables

* feat: update sidebar item styles

* feat: update collapse icon and styles

* fix: name not updated in menu on change

* fix: show invite members nav item

* fix: open invite members modal on invite team member nav item click
2024-01-05 11:15:31 +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
866 changed files with 53490 additions and 5905 deletions

2
.github/CODEOWNERS vendored
View File

@@ -2,7 +2,7 @@
# Owners are automatically requested for review for PRs that changes code # Owners are automatically requested for review for PRs that changes code
# that they own. # that they own.
/frontend/ @palashgdev @YounixM /frontend/ @YounixM
/frontend/src/container/MetricsApplication @srikanthccv /frontend/src/container/MetricsApplication @srikanthccv
/frontend/src/container/NewWidget/RightContainer/types.ts @srikanthccv /frontend/src/container/NewWidget/RightContainer/types.ts @srikanthccv
/deploy/ @prashant-shahi /deploy/ @prashant-shahi

View File

@@ -19,4 +19,4 @@ jobs:
- name: 'Dependency Review' - name: 'Dependency Review'
with: with:
fail-on-severity: high fail-on-severity: high
uses: actions/dependency-review-action@v2 uses: actions/dependency-review-action@v3

View File

@@ -15,6 +15,11 @@ jobs:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Setup golang
uses: actions/setup-go@v4
with:
go-version: "1.21"
- name: Build query-service image - name: Build query-service image
env: env:
DEV_BUILD: 1 DEV_BUILD: 1
@@ -65,9 +70,9 @@ jobs:
- name: Kick off a sample-app workload - name: Kick off a sample-app workload
run: | run: |
# start the locust swarm # start the locust swarm
kubectl -n sample-application run strzal --image=djbingham/curl \ kubectl --namespace sample-application run strzal --image=djbingham/curl \
--restart='OnFailure' -i --rm --command -- curl -X POST -F \ --restart='OnFailure' -i --tty --rm --command -- curl -X POST -F \
'locust_count=6' -F 'hatch_rate=2' http://locust-master:8089/swarm 'user_count=6' -F 'spawn_rate=2' http://locust-master:8089/swarm
- name: Get short commit SHA, display tunnel URL and IP Address of the worker node - name: Get short commit SHA, display tunnel URL and IP Address of the worker node
id: get-subdomain id: get-subdomain

View File

@@ -20,13 +20,13 @@ jobs:
with: with:
go-version: "1.21" go-version: "1.21"
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v2 uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v3
with: with:
version: latest version: latest
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@v2 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -64,13 +64,13 @@ jobs:
with: with:
go-version: "1.21" go-version: "1.21"
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v2 uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v3
with: with:
version: latest version: latest
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@v2 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -115,11 +115,11 @@ jobs:
run: npm run lint run: npm run lint
continue-on-error: true continue-on-error: true
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v3
with: with:
version: latest version: latest
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@v2 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -152,6 +152,12 @@ jobs:
echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > frontend/.env echo 'INTERCOM_APP_ID="${{ secrets.INTERCOM_APP_ID }}"' > frontend/.env
echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env echo 'SEGMENT_ID="${{ secrets.SEGMENT_ID }}"' >> frontend/.env
echo 'CLARITY_PROJECT_ID="${{ secrets.CLARITY_PROJECT_ID }}"' >> frontend/.env echo 'CLARITY_PROJECT_ID="${{ secrets.CLARITY_PROJECT_ID }}"' >> frontend/.env
echo 'SENTRY_AUTH_TOKEN="${{ secrets.SENTRY_AUTH_TOKEN }}"' >> frontend/.env
echo 'SENTRY_ORG="${{ secrets.SENTRY_ORG }}"' >> frontend/.env
echo 'SENTRY_PROJECT_ID="${{ secrets.SENTRY_PROJECT_ID }}"' >> frontend/.env
echo 'SENTRY_DSN="${{ secrets.SENTRY_DSN }}"' >> frontend/.env
echo 'TUNNEL_URL="${{ secrets.TUNNEL_URL }}"' >> frontend/.env
echo 'TUNNEL_DOMAIN="${{ secrets.TUNNEL_DOMAIN }}"' >> frontend/.env
- name: Install dependencies - name: Install dependencies
working-directory: frontend working-directory: frontend
run: yarn install run: yarn install
@@ -164,11 +170,11 @@ jobs:
run: npm run lint run: npm run lint
continue-on-error: true continue-on-error: true
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v3
with: with:
version: latest version: latest
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@v2 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}

View File

@@ -11,7 +11,7 @@ jobs:
environment: staging environment: staging
steps: steps:
- name: Executing remote ssh commands using ssh key - name: Executing remote ssh commands using ssh key
uses: appleboy/ssh-action@v0.1.8 uses: appleboy/ssh-action@v1.0.3
env: env:
GITHUB_BRANCH: develop GITHUB_BRANCH: develop
GITHUB_SHA: ${{ github.sha }} GITHUB_SHA: ${{ github.sha }}

View File

@@ -11,7 +11,7 @@ jobs:
if: ${{ github.event.label.name == 'testing-deploy' }} if: ${{ github.event.label.name == 'testing-deploy' }}
steps: steps:
- name: Executing remote ssh commands using ssh key - name: Executing remote ssh commands using ssh key
uses: appleboy/ssh-action@v0.1.8 uses: appleboy/ssh-action@v1.0.3
env: env:
GITHUB_BRANCH: ${{ github.head_ref || github.ref_name }} GITHUB_BRANCH: ${{ github.head_ref || github.ref_name }}
GITHUB_SHA: ${{ github.sha }} GITHUB_SHA: ${{ github.sha }}
@@ -33,8 +33,11 @@ jobs:
git add . git add .
git stash push -m "stashed on $(date --iso-8601=seconds)" git stash push -m "stashed on $(date --iso-8601=seconds)"
git fetch origin git fetch origin
git checkout ${GITHUB_BRANCH} git checkout develop
git pull git pull
# This is added to include the scenerio when new commit in PR is force-pushed
git branch -D ${GITHUB_BRANCH}
git checkout --track origin/${GITHUB_BRANCH}
make build-ee-query-service-amd64 make build-ee-query-service-amd64
make build-frontend-amd64 make build-frontend-amd64
make run-signoz make run-signoz

View File

@@ -11,7 +11,6 @@
<img alt="tweet" src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a> <img alt="tweet" src="https://img.shields.io/twitter/url/http/shields.io.svg?style=social"> </a>
</p> </p>
<h3 align="center"> <h3 align="center">
<a href="https://signoz.io/docs"><b>Dokumentation</b></a> &bull; <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; <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. 👉 Einfache Einrichtung von Benachrichtigungen mit dem selbst erstellbaren Abfrage-Builder.
## ##
### Anwendung Metriken ### Anwendung Metriken
![application_metrics](https://user-images.githubusercontent.com/83692067/226637410-900dbc5e-6705-4b11-a10c-bd0faeb2a92f.png) ![application_metrics](https://user-images.githubusercontent.com/83692067/226637410-900dbc5e-6705-4b11-a10c-bd0faeb2a92f.png)
### Verteiltes Tracing ### 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_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"> <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) ![exceptions_light](https://user-images.githubusercontent.com/83692067/226637967-4188d024-3ac9-4799-be95-f5ea9c45436f.png)
### Alarme ### Alarme
<img width="2068" alt="alerts_management" src="https://user-images.githubusercontent.com/83692067/226536548-2c81e2e8-c12d-47e8-bad7-c6be79055def.png"> <img width="2068" alt="alerts_management" src="https://user-images.githubusercontent.com/83692067/226536548-2c81e2e8-c12d-47e8-bad7-c6be79055def.png">
<br /><br /> <br /><br />
## Werde Teil unserer Slack Community ## Werde Teil unserer Slack Community
Sag Hi zu uns auf [Slack](https://signoz.io/slack) 👋 Sag Hi zu uns auf [Slack](https://signoz.io/slack) 👋
<br /><br /> <br /><br />
## Funktionen: ## 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. - 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 /> <br /><br />
## Wieso SigNoz? ## 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. 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 - Elixir
- Rust - Rust
Hier findest du die vollständige Liste von unterstützten Programmiersprachen - https://opentelemetry.io/docs/ Hier findest du die vollständige Liste von unterstützten Programmiersprachen - https://opentelemetry.io/docs/
<br /><br /> <br /><br />
## Erste Schritte mit SigNoz ## Erste Schritte mit SigNoz
### Bereitstellung mit Docker ### Bereitstellung mit Docker
@@ -138,7 +131,6 @@ Bitte folge den [hier](https://signoz.io/docs/deployment/helm_chart) aufgelistet
<br /><br /> <br /><br />
## Vergleiche mit bekannten Tools ## Vergleiche mit bekannten Tools
### SigNoz vs Prometheus ### SigNoz vs Prometheus
@@ -179,7 +171,6 @@ Wir haben Benchmarks veröffentlicht, die Loki mit SigNoz vergleichen. Schauen S
<br /><br /> <br /><br />
## Zum Projekt beitragen ## 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. 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 #### Frontend
- [Palash Gupta](https://github.com/palashgdev) - [Palash Gupta](https://github.com/palashgdev)
- [Yunus M](https://github.com/YounixM)
- [Rajat Dabade](https://github.com/Rajat-Dabade)
#### DevOps #### DevOps
@@ -204,16 +197,12 @@ Du bist dir nicht sicher, wie du anfangen sollst? Schreib uns einfach auf dem #c
<br /><br /> <br /><br />
## Dokumentation ## 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. 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 /> <br /><br />
## Gemeinschaft ## 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. 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

@@ -108,7 +108,7 @@ We support [OpenTelemetry](https://opentelemetry.io) as the library which you ca
- Java - Java
- Python - Python
- NodeJS - Node.js
- Go - Go
- PHP - PHP
- .NET - .NET

View File

@@ -19,7 +19,7 @@
<a href="https://twitter.com/SigNozHq"><b>Twitter</b></a> <a href="https://twitter.com/SigNozHq"><b>Twitter</b></a>
</h3> </h3>
## ##
SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可以使用 SigNoz 实现如下能力: SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可以使用 SigNoz 实现如下能力:
@@ -67,7 +67,7 @@ SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可
## 加入我们 Slack 社区 ## 加入我们 Slack 社区
来 [Slack](https://signoz.io/slack) 和我们打招呼吧 👋 来 [Slack](https://signoz.io/slack) 和我们打招呼吧 👋
<br /><br /> <br /><br />
@@ -83,7 +83,7 @@ SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可
- 通过 服务名、操作方式、延迟、错误、标签/注释 过滤 traces 数据 - 通过 服务名、操作方式、延迟、错误、标签/注释 过滤 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 相关日志 - 原生支持 OpenTelemetry 日志,高级日志查询,自动收集 k8s 相关日志
@@ -101,7 +101,7 @@ SigNoz 帮助开发人员监控应用并排查已部署应用的问题。你可
我们想做一个自托管并且可开源的工具,像 DataDog 和 NewRelic 那样, 为那些担心数据隐私和安全的公司提供第三方服务。 我们想做一个自托管并且可开源的工具,像 DataDog 和 NewRelic 那样, 为那些担心数据隐私和安全的公司提供第三方服务。
作为开源的项目,你完全可以自己掌控你的配置、样本和更新。你同样可以基于 SigNoz 拓展特定的业务模块。 作为开源的项目,你完全可以自己掌控你的配置、样本和更新。你同样可以基于 SigNoz 拓展特定的业务模块。
### 支持的编程语言: ### 支持的编程语言:
@@ -153,9 +153,9 @@ Jaeger 仅仅是一个分布式追踪系统。 但是 SigNoz 可以提供 metric
而且, SigNoz 相较于 Jaeger 拥有更对的高级功能: 而且, 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> <p>&nbsp </p>
@@ -185,7 +185,7 @@ Jaeger 仅仅是一个分布式追踪系统。 但是 SigNoz 可以提供 metric
我们 ❤️ 你的贡献,无论大小。 请先阅读 [CONTRIBUTING.md](CONTRIBUTING.md) 再开始给 SigNoz 做贡献。 我们 ❤️ 你的贡献,无论大小。 请先阅读 [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) - [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" version: "3.9"
x-clickhouse-defaults: &clickhouse-defaults x-clickhouse-defaults: &clickhouse-defaults
image: clickhouse/clickhouse-server:23.11.1-alpine image: clickhouse/clickhouse-server:24.1.2-alpine
tty: true tty: true
deploy: deploy:
restart_policy: restart_policy:
@@ -133,7 +133,7 @@ services:
# - ./data/clickhouse-3/:/var/lib/clickhouse/ # - ./data/clickhouse-3/:/var/lib/clickhouse/
alertmanager: alertmanager:
image: signoz/alertmanager:0.23.4 image: signoz/alertmanager:0.23.5
volumes: volumes:
- ./data/alertmanager:/data - ./data/alertmanager:/data
command: command:
@@ -146,11 +146,11 @@ services:
condition: on-failure condition: on-failure
query-service: query-service:
image: signoz/query-service:0.36.0 image: signoz/query-service:0.41.1
command: command:
[ [
"-config=/root/config/prometheus.yml", "-config=/root/config/prometheus.yml",
"--prefer-delta=true" # "--prefer-delta=true"
] ]
# ports: # ports:
# - "6060:6060" # pprof port # - "6060:6060" # pprof port
@@ -160,7 +160,7 @@ services:
- ../dashboards:/root/config/dashboards - ../dashboards:/root/config/dashboards
- ./data/signoz/:/var/lib/signoz/ - ./data/signoz/:/var/lib/signoz/
environment: environment:
- ClickHouseUrl=tcp://clickhouse:9000/?database=signoz_traces - ClickHouseUrl=tcp://clickhouse:9000
- ALERTMANAGER_API_PREFIX=http://alertmanager:9093/api/ - ALERTMANAGER_API_PREFIX=http://alertmanager:9093/api/
- SIGNOZ_LOCAL_DB_PATH=/var/lib/signoz/signoz.db - SIGNOZ_LOCAL_DB_PATH=/var/lib/signoz/signoz.db
- DASHBOARDS_PATH=/root/config/dashboards - DASHBOARDS_PATH=/root/config/dashboards
@@ -186,7 +186,7 @@ services:
<<: *db-depend <<: *db-depend
frontend: frontend:
image: signoz/frontend:0.36.0 image: signoz/frontend:0.41.1
deploy: deploy:
restart_policy: restart_policy:
condition: on-failure condition: on-failure
@@ -199,7 +199,7 @@ services:
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf - ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
otel-collector: otel-collector:
image: signoz/signoz-otel-collector:0.88.4 image: signoz/signoz-otel-collector:0.88.15
command: command:
[ [
"--config=/etc/otel-collector-config.yaml", "--config=/etc/otel-collector-config.yaml",
@@ -237,7 +237,7 @@ services:
- query-service - query-service
otel-collector-migrator: otel-collector-migrator:
image: signoz/signoz-schema-migrator:0.88.4 image: signoz/signoz-schema-migrator:0.88.15
deploy: deploy:
restart_policy: restart_policy:
condition: on-failure condition: on-failure
@@ -249,25 +249,6 @@ services:
# - clickhouse-2 # - clickhouse-2
# - clickhouse-3 # - clickhouse-3
otel-collector-metrics:
image: signoz/signoz-otel-collector:0.88.4
command:
[
"--config=/etc/otel-collector-metrics-config.yaml",
"--feature-gates=-pkg.translator.prometheus.NormalizeName"
]
volumes:
- ./otel-collector-metrics-config.yaml:/etc/otel-collector-metrics-config.yaml
# ports:
# - "1777:1777" # pprof extension
# - "8888:8888" # OtelCollector internal metrics
# - "13133:13133" # Health check extension
# - "55679:55679" # zPages extension
deploy:
restart_policy:
condition: on-failure
<<: *db-depend
logspout: logspout:
image: "gliderlabs/logspout:v3.2.14" image: "gliderlabs/logspout:v3.2.14"
volumes: volumes:

View File

@@ -15,13 +15,9 @@ receivers:
# please remove names from below if you want to collect logs from them # please remove names from below if you want to collect logs from them
- type: filter - type: filter
id: signoz_logs_filter id: signoz_logs_filter
expr: 'attributes.container_name matches "^signoz_(logspout|frontend|alertmanager|query-service|otel-collector|otel-collector-metrics|clickhouse|zookeeper)"' expr: 'attributes.container_name matches "^signoz_(logspout|frontend|alertmanager|query-service|otel-collector|clickhouse|zookeeper)"'
opencensus: opencensus:
endpoint: 0.0.0.0:55678 endpoint: 0.0.0.0:55678
otlp/spanmetrics:
protocols:
grpc:
endpoint: localhost:12345
otlp: otlp:
protocols: protocols:
grpc: grpc:
@@ -69,8 +65,8 @@ processors:
# Using OTEL_RESOURCE_ATTRIBUTES envvar, env detector adds custom labels. # Using OTEL_RESOURCE_ATTRIBUTES envvar, env detector adds custom labels.
detectors: [env, system] # include ec2 for AWS, gcp for GCP and azure for Azure. detectors: [env, system] # include ec2 for AWS, gcp for GCP and azure for Azure.
timeout: 2s timeout: 2s
signozspanmetrics/prometheus: signozspanmetrics/cumulative:
metrics_exporter: prometheus metrics_exporter: clickhousemetricswrite
latency_histogram_buckets: [100us, 1ms, 2ms, 6ms, 10ms, 50ms, 100ms, 250ms, 500ms, 1000ms, 1400ms, 2000ms, 5s, 10s, 20s, 40s, 60s ] latency_histogram_buckets: [100us, 1ms, 2ms, 6ms, 10ms, 50ms, 100ms, 250ms, 500ms, 1000ms, 1400ms, 2000ms, 5s, 10s, 20s, 40s, 60s ]
dimensions_cache_size: 100000 dimensions_cache_size: 100000
dimensions: dimensions:
@@ -97,6 +93,21 @@ processors:
# num_workers: 4 # num_workers: 4
# queue_size: 100 # queue_size: 100
# retry_on_failure: true # retry_on_failure: true
signozspanmetrics/delta:
metrics_exporter: clickhousemetricswrite
latency_histogram_buckets: [100us, 1ms, 2ms, 6ms, 10ms, 50ms, 100ms, 250ms, 500ms, 1000ms, 1400ms, 2000ms, 5s, 10s, 20s, 40s, 60s ]
dimensions_cache_size: 100000
aggregation_temporality: AGGREGATION_TEMPORALITY_DELTA
enable_exp_histogram: true
dimensions:
- name: service.namespace
default: default
- name: deployment.environment
default: default
# This is added to ensure the uniqueness of the timeseries
# Otherwise, identical timeseries produced by multiple replicas of
# collectors result in incorrect APM metrics
- name: signoz.collector.id
exporters: exporters:
clickhousetraces: clickhousetraces:
@@ -109,21 +120,11 @@ exporters:
enabled: true enabled: true
clickhousemetricswrite/prometheus: clickhousemetricswrite/prometheus:
endpoint: tcp://clickhouse:9000/?database=signoz_metrics endpoint: tcp://clickhouse:9000/?database=signoz_metrics
prometheus:
endpoint: 0.0.0.0:8889
# logging: {} # logging: {}
clickhouselogsexporter: clickhouselogsexporter:
dsn: tcp://clickhouse:9000/ dsn: tcp://clickhouse:9000/
docker_multi_node_cluster: ${DOCKER_MULTI_NODE_CLUSTER} docker_multi_node_cluster: ${DOCKER_MULTI_NODE_CLUSTER}
timeout: 5s timeout: 10s
sending_queue:
queue_size: 100
retry_on_failure:
enabled: true
initial_interval: 5s
max_interval: 30s
max_elapsed_time: 300s
extensions: extensions:
health_check: health_check:
endpoint: 0.0.0.0:13133 endpoint: 0.0.0.0:13133
@@ -140,7 +141,7 @@ service:
pipelines: pipelines:
traces: traces:
receivers: [jaeger, otlp] receivers: [jaeger, otlp]
processors: [signozspanmetrics/prometheus, batch] processors: [signozspanmetrics/cumulative, signozspanmetrics/delta, batch]
exporters: [clickhousetraces] exporters: [clickhousetraces]
metrics: metrics:
receivers: [otlp] receivers: [otlp]
@@ -154,9 +155,6 @@ service:
receivers: [prometheus] receivers: [prometheus]
processors: [batch] processors: [batch]
exporters: [clickhousemetricswrite/prometheus] exporters: [clickhousemetricswrite/prometheus]
metrics/spanmetrics:
receivers: [otlp/spanmetrics]
exporters: [prometheus]
logs: logs:
receivers: [otlp, tcplog/docker] receivers: [otlp, tcplog/docker]
processors: [batch] processors: [batch]

View File

@@ -1,64 +0,0 @@
receivers:
prometheus:
config:
scrape_configs:
# otel-collector-metrics internal metrics
- job_name: otel-collector-metrics
scrape_interval: 60s
static_configs:
- targets:
- localhost:8888
labels:
job_name: otel-collector-metrics
# SigNoz span metrics
- job_name: signozspanmetrics-collector
scrape_interval: 60s
dns_sd_configs:
- names:
- tasks.otel-collector
type: A
port: 8889
processors:
batch:
send_batch_size: 10000
send_batch_max_size: 11000
timeout: 10s
# memory_limiter:
# # 80% of maximum memory up to 2G
# limit_mib: 1500
# # 25% of limit up to 2G
# spike_limit_mib: 512
# check_interval: 5s
#
# # 50% of the maximum memory
# limit_percentage: 50
# # 20% of max memory usage spike expected
# spike_limit_percentage: 20
# queued_retry:
# num_workers: 4
# queue_size: 100
# retry_on_failure: true
exporters:
clickhousemetricswrite:
endpoint: tcp://clickhouse:9000/?database=signoz_metrics
extensions:
health_check:
endpoint: 0.0.0.0:13133
zpages:
endpoint: 0.0.0.0:55679
pprof:
endpoint: 0.0.0.0:1777
service:
telemetry:
metrics:
address: 0.0.0.0:8888
extensions: [health_check, zpages, pprof]
pipelines:
metrics:
receivers: [prometheus]
processors: [batch]
exporters: [clickhousemetricswrite]

View File

@@ -19,7 +19,7 @@ services:
- ZOO_AUTOPURGE_INTERVAL=1 - ZOO_AUTOPURGE_INTERVAL=1
clickhouse: clickhouse:
image: clickhouse/clickhouse-server:23.7.3-alpine image: clickhouse/clickhouse-server:24.1.2-alpine
container_name: signoz-clickhouse container_name: signoz-clickhouse
# ports: # ports:
# - "9000:9000" # - "9000:9000"
@@ -54,7 +54,7 @@ services:
alertmanager: alertmanager:
container_name: signoz-alertmanager container_name: signoz-alertmanager
image: signoz/alertmanager:0.23.4 image: signoz/alertmanager:0.23.5
volumes: volumes:
- ./data/alertmanager:/data - ./data/alertmanager:/data
depends_on: depends_on:
@@ -66,7 +66,7 @@ services:
- --storage.path=/data - --storage.path=/data
otel-collector-migrator: otel-collector-migrator:
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.4} image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.15}
container_name: otel-migrator container_name: otel-migrator
command: command:
- "--dsn=tcp://clickhouse:9000" - "--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` # 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: otel-collector:
container_name: signoz-otel-collector container_name: signoz-otel-collector
image: signoz/signoz-otel-collector:0.88.4 image: signoz/signoz-otel-collector:0.88.15
command: command:
[ [
"--config=/etc/otel-collector-config.yaml", "--config=/etc/otel-collector-config.yaml",
@@ -116,28 +116,6 @@ services:
query-service: query-service:
condition: service_healthy condition: service_healthy
otel-collector-metrics:
container_name: signoz-otel-collector-metrics
image: signoz/signoz-otel-collector:0.88.4
command:
[
"--config=/etc/otel-collector-metrics-config.yaml",
"--feature-gates=-pkg.translator.prometheus.NormalizeName"
]
volumes:
- ./otel-collector-metrics-config.yaml:/etc/otel-collector-metrics-config.yaml
# ports:
# - "1777:1777" # pprof extension
# - "8888:8888" # OtelCollector internal metrics
# - "13133:13133" # Health check extension
# - "55679:55679" # zPages extension
restart: on-failure
depends_on:
clickhouse:
condition: service_healthy
otel-collector-migrator:
condition: service_completed_successfully
logspout: logspout:
image: "gliderlabs/logspout:v3.2.14" image: "gliderlabs/logspout:v3.2.14"
container_name: signoz-logspout container_name: signoz-logspout

View File

@@ -25,7 +25,7 @@ services:
command: command:
[ [
"-config=/root/config/prometheus.yml", "-config=/root/config/prometheus.yml",
"--prefer-delta=true" # "--prefer-delta=true"
] ]
ports: ports:
- "6060:6060" - "6060:6060"

View File

@@ -3,7 +3,7 @@ version: "2.4"
x-clickhouse-defaults: &clickhouse-defaults x-clickhouse-defaults: &clickhouse-defaults
restart: on-failure restart: on-failure
# addding non LTS version due to this fix https://github.com/ClickHouse/ClickHouse/commit/32caf8716352f45c1b617274c7508c86b7d1afab # addding non LTS version due to this fix https://github.com/ClickHouse/ClickHouse/commit/32caf8716352f45c1b617274c7508c86b7d1afab
image: clickhouse/clickhouse-server:23.11.1-alpine image: clickhouse/clickhouse-server:24.1.2-alpine
tty: true tty: true
depends_on: depends_on:
- zookeeper-1 - zookeeper-1
@@ -149,7 +149,7 @@ services:
# - ./user_scripts:/var/lib/clickhouse/user_scripts/ # - ./user_scripts:/var/lib/clickhouse/user_scripts/
alertmanager: alertmanager:
image: signoz/alertmanager:${ALERTMANAGER_TAG:-0.23.4} image: signoz/alertmanager:${ALERTMANAGER_TAG:-0.23.5}
container_name: signoz-alertmanager container_name: signoz-alertmanager
volumes: volumes:
- ./data/alertmanager:/data - ./data/alertmanager:/data
@@ -164,12 +164,12 @@ services:
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md` # 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: query-service:
image: signoz/query-service:${DOCKER_TAG:-0.36.0} image: signoz/query-service:${DOCKER_TAG:-0.41.1}
container_name: signoz-query-service container_name: signoz-query-service
command: command:
[ [
"-config=/root/config/prometheus.yml", "-config=/root/config/prometheus.yml",
"--prefer-delta=true" # "--prefer-delta=true"
] ]
# ports: # ports:
# - "6060:6060" # pprof port # - "6060:6060" # pprof port
@@ -179,7 +179,7 @@ services:
- ../dashboards:/root/config/dashboards - ../dashboards:/root/config/dashboards
- ./data/signoz/:/var/lib/signoz/ - ./data/signoz/:/var/lib/signoz/
environment: environment:
- ClickHouseUrl=tcp://clickhouse:9000/?database=signoz_traces - ClickHouseUrl=tcp://clickhouse:9000
- ALERTMANAGER_API_PREFIX=http://alertmanager:9093/api/ - ALERTMANAGER_API_PREFIX=http://alertmanager:9093/api/
- SIGNOZ_LOCAL_DB_PATH=/var/lib/signoz/signoz.db - SIGNOZ_LOCAL_DB_PATH=/var/lib/signoz/signoz.db
- DASHBOARDS_PATH=/root/config/dashboards - DASHBOARDS_PATH=/root/config/dashboards
@@ -203,7 +203,7 @@ services:
<<: *db-depend <<: *db-depend
frontend: frontend:
image: signoz/frontend:${DOCKER_TAG:-0.36.0} image: signoz/frontend:${DOCKER_TAG:-0.41.1}
container_name: signoz-frontend container_name: signoz-frontend
restart: on-failure restart: on-failure
depends_on: depends_on:
@@ -215,7 +215,7 @@ services:
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf - ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
otel-collector-migrator: otel-collector-migrator:
image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.4} image: signoz/signoz-schema-migrator:${OTELCOL_TAG:-0.88.15}
container_name: otel-migrator container_name: otel-migrator
command: command:
- "--dsn=tcp://clickhouse:9000" - "--dsn=tcp://clickhouse:9000"
@@ -229,7 +229,7 @@ services:
otel-collector: otel-collector:
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.88.4} image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.88.15}
container_name: signoz-otel-collector container_name: signoz-otel-collector
command: command:
[ [
@@ -268,24 +268,6 @@ services:
query-service: query-service:
condition: service_healthy condition: service_healthy
otel-collector-metrics:
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.88.4}
container_name: signoz-otel-collector-metrics
command:
[
"--config=/etc/otel-collector-metrics-config.yaml",
"--feature-gates=-pkg.translator.prometheus.NormalizeName"
]
volumes:
- ./otel-collector-metrics-config.yaml:/etc/otel-collector-metrics-config.yaml
# ports:
# - "1777:1777" # pprof extension
# - "8888:8888" # OtelCollector internal metrics
# - "13133:13133" # Health check extension
# - "55679:55679" # zPages extension
restart: on-failure
<<: *db-depend
logspout: logspout:
image: "gliderlabs/logspout:v3.2.14" image: "gliderlabs/logspout:v3.2.14"
container_name: signoz-logspout container_name: signoz-logspout

View File

@@ -15,13 +15,9 @@ receivers:
# please remove names from below if you want to collect logs from them # please remove names from below if you want to collect logs from them
- type: filter - type: filter
id: signoz_logs_filter id: signoz_logs_filter
expr: 'attributes.container_name matches "^signoz-(logspout|frontend|alertmanager|query-service|otel-collector|otel-collector-metrics|clickhouse|zookeeper)"' expr: 'attributes.container_name matches "^signoz-(logspout|frontend|alertmanager|query-service|otel-collector|clickhouse|zookeeper)"'
opencensus: opencensus:
endpoint: 0.0.0.0:55678 endpoint: 0.0.0.0:55678
otlp/spanmetrics:
protocols:
grpc:
endpoint: localhost:12345
otlp: otlp:
protocols: protocols:
grpc: grpc:
@@ -66,8 +62,9 @@ processors:
send_batch_size: 10000 send_batch_size: 10000
send_batch_max_size: 11000 send_batch_max_size: 11000
timeout: 10s timeout: 10s
signozspanmetrics/prometheus: signozspanmetrics/cumulative:
metrics_exporter: prometheus metrics_exporter: clickhousemetricswrite
metrics_flush_interval: 60s
latency_histogram_buckets: [100us, 1ms, 2ms, 6ms, 10ms, 50ms, 100ms, 250ms, 500ms, 1000ms, 1400ms, 2000ms, 5s, 10s, 20s, 40s, 60s ] latency_histogram_buckets: [100us, 1ms, 2ms, 6ms, 10ms, 50ms, 100ms, 250ms, 500ms, 1000ms, 1400ms, 2000ms, 5s, 10s, 20s, 40s, 60s ]
dimensions_cache_size: 100000 dimensions_cache_size: 100000
dimensions: dimensions:
@@ -98,6 +95,22 @@ processors:
# Using OTEL_RESOURCE_ATTRIBUTES envvar, env detector adds custom labels. # Using OTEL_RESOURCE_ATTRIBUTES envvar, env detector adds custom labels.
detectors: [env, system] # include ec2 for AWS, gcp for GCP and azure for Azure. detectors: [env, system] # include ec2 for AWS, gcp for GCP and azure for Azure.
timeout: 2s timeout: 2s
signozspanmetrics/delta:
metrics_exporter: clickhousemetricswrite
metrics_flush_interval: 60s
latency_histogram_buckets: [100us, 1ms, 2ms, 6ms, 10ms, 50ms, 100ms, 250ms, 500ms, 1000ms, 1400ms, 2000ms, 5s, 10s, 20s, 40s, 60s ]
dimensions_cache_size: 100000
aggregation_temporality: AGGREGATION_TEMPORALITY_DELTA
enable_exp_histogram: true
dimensions:
- name: service.namespace
default: default
- name: deployment.environment
default: default
# This is added to ensure the uniqueness of the timeseries
# Otherwise, identical timeseries produced by multiple replicas of
# collectors result in incorrect APM metrics
- name: signoz.collector.id
extensions: extensions:
health_check: health_check:
@@ -118,21 +131,12 @@ exporters:
enabled: true enabled: true
clickhousemetricswrite/prometheus: clickhousemetricswrite/prometheus:
endpoint: tcp://clickhouse:9000/?database=signoz_metrics endpoint: tcp://clickhouse:9000/?database=signoz_metrics
prometheus:
endpoint: 0.0.0.0:8889
# logging: {} # logging: {}
clickhouselogsexporter: clickhouselogsexporter:
dsn: tcp://clickhouse:9000/ dsn: tcp://clickhouse:9000/
docker_multi_node_cluster: ${DOCKER_MULTI_NODE_CLUSTER} docker_multi_node_cluster: ${DOCKER_MULTI_NODE_CLUSTER}
timeout: 5s timeout: 10s
sending_queue:
queue_size: 100
retry_on_failure:
enabled: true
initial_interval: 5s
max_interval: 30s
max_elapsed_time: 300s
service: service:
telemetry: telemetry:
@@ -145,7 +149,7 @@ service:
pipelines: pipelines:
traces: traces:
receivers: [jaeger, otlp] receivers: [jaeger, otlp]
processors: [signozspanmetrics/prometheus, batch] processors: [signozspanmetrics/cumulative, signozspanmetrics/delta, batch]
exporters: [clickhousetraces] exporters: [clickhousetraces]
metrics: metrics:
receivers: [otlp] receivers: [otlp]
@@ -159,9 +163,6 @@ service:
receivers: [prometheus] receivers: [prometheus]
processors: [batch] processors: [batch]
exporters: [clickhousemetricswrite/prometheus] exporters: [clickhousemetricswrite/prometheus]
metrics/spanmetrics:
receivers: [otlp/spanmetrics]
exporters: [prometheus]
logs: logs:
receivers: [otlp, tcplog/docker] receivers: [otlp, tcplog/docker]
processors: [batch] processors: [batch]

View File

@@ -1,69 +0,0 @@
receivers:
otlp:
protocols:
grpc:
http:
prometheus:
config:
scrape_configs:
# otel-collector-metrics internal metrics
- job_name: otel-collector-metrics
scrape_interval: 60s
static_configs:
- targets:
- localhost:8888
labels:
job_name: otel-collector-metrics
# SigNoz span metrics
- job_name: signozspanmetrics-collector
scrape_interval: 60s
static_configs:
- targets:
- otel-collector:8889
processors:
batch:
send_batch_size: 10000
send_batch_max_size: 11000
timeout: 10s
# memory_limiter:
# # 80% of maximum memory up to 2G
# limit_mib: 1500
# # 25% of limit up to 2G
# spike_limit_mib: 512
# check_interval: 5s
#
# # 50% of the maximum memory
# limit_percentage: 50
# # 20% of max memory usage spike expected
# spike_limit_percentage: 20
# queued_retry:
# num_workers: 4
# queue_size: 100
# retry_on_failure: true
extensions:
health_check:
endpoint: 0.0.0.0:13133
zpages:
endpoint: 0.0.0.0:55679
pprof:
endpoint: 0.0.0.0:1777
exporters:
clickhousemetricswrite:
endpoint: tcp://clickhouse:9000/?database=signoz_metrics
service:
telemetry:
metrics:
address: 0.0.0.0:8888
extensions:
- health_check
- zpages
- pprof
pipelines:
metrics:
receivers: [prometheus]
processors: [batch]
exporters: [clickhousemetricswrite]

View File

@@ -1,5 +1,5 @@
# use a minimal alpine image # use a minimal alpine image
FROM alpine:3.18.5 FROM alpine:3.18.6
# Add Maintainer Info # Add Maintainer Info
LABEL maintainer="signoz" LABEL maintainer="signoz"

View File

@@ -10,6 +10,7 @@ import (
"go.signoz.io/signoz/ee/query-service/license" "go.signoz.io/signoz/ee/query-service/license"
"go.signoz.io/signoz/ee/query-service/usage" "go.signoz.io/signoz/ee/query-service/usage"
baseapp "go.signoz.io/signoz/pkg/query-service/app" baseapp "go.signoz.io/signoz/pkg/query-service/app"
"go.signoz.io/signoz/pkg/query-service/app/integrations"
"go.signoz.io/signoz/pkg/query-service/app/logparsingpipeline" "go.signoz.io/signoz/pkg/query-service/app/logparsingpipeline"
"go.signoz.io/signoz/pkg/query-service/cache" "go.signoz.io/signoz/pkg/query-service/cache"
baseint "go.signoz.io/signoz/pkg/query-service/interfaces" baseint "go.signoz.io/signoz/pkg/query-service/interfaces"
@@ -31,6 +32,7 @@ type APIHandlerOptions struct {
UsageManager *usage.Manager UsageManager *usage.Manager
FeatureFlags baseint.FeatureLookup FeatureFlags baseint.FeatureLookup
LicenseManager *license.Manager LicenseManager *license.Manager
IntegrationsController *integrations.Controller
LogsParsingPipelineController *logparsingpipeline.LogParsingPipelineController LogsParsingPipelineController *logparsingpipeline.LogParsingPipelineController
Cache cache.Cache Cache cache.Cache
// Querier Influx Interval // Querier Influx Interval
@@ -56,6 +58,7 @@ func NewAPIHandler(opts APIHandlerOptions) (*APIHandler, error) {
AppDao: opts.AppDao, AppDao: opts.AppDao,
RuleManager: opts.RulesManager, RuleManager: opts.RulesManager,
FeatureFlags: opts.FeatureFlags, FeatureFlags: opts.FeatureFlags,
IntegrationsController: opts.IntegrationsController,
LogsParsingPipelineController: opts.LogsParsingPipelineController, LogsParsingPipelineController: opts.LogsParsingPipelineController,
Cache: opts.Cache, Cache: opts.Cache,
FluxInterval: opts.FluxInterval, FluxInterval: opts.FluxInterval,
@@ -152,9 +155,10 @@ func (ah *APIHandler) RegisterRoutes(router *mux.Router, am *baseapp.AuthMiddlew
router.HandleFunc("/api/v2/metrics/query_range", am.ViewAccess(ah.queryRangeMetricsV2)).Methods(http.MethodPost) router.HandleFunc("/api/v2/metrics/query_range", am.ViewAccess(ah.queryRangeMetricsV2)).Methods(http.MethodPost)
// PAT APIs // PAT APIs
router.HandleFunc("/api/v1/pat", am.OpenAccess(ah.createPAT)).Methods(http.MethodPost) router.HandleFunc("/api/v1/pats", am.AdminAccess(ah.createPAT)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/pat", am.OpenAccess(ah.getPATs)).Methods(http.MethodGet) router.HandleFunc("/api/v1/pats", am.AdminAccess(ah.getPATs)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/pat/{id}", am.OpenAccess(ah.deletePAT)).Methods(http.MethodDelete) router.HandleFunc("/api/v1/pats/{id}", am.AdminAccess(ah.updatePAT)).Methods(http.MethodPut)
router.HandleFunc("/api/v1/pats/{id}", am.AdminAccess(ah.revokePAT)).Methods(http.MethodDelete)
router.HandleFunc("/api/v1/checkout", am.AdminAccess(ah.checkout)).Methods(http.MethodPost) router.HandleFunc("/api/v1/checkout", am.AdminAccess(ah.checkout)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/billing", am.AdminAccess(ah.getBilling)).Methods(http.MethodGet) router.HandleFunc("/api/v1/billing", am.AdminAccess(ah.getBilling)).Methods(http.MethodGet)

View File

@@ -12,6 +12,20 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
type DayWiseBreakdown struct {
Type string `json:"type"`
Breakdown []DayWiseData `json:"breakdown"`
}
type DayWiseData struct {
Timestamp int64 `json:"timestamp"`
Count float64 `json:"count"`
Size float64 `json:"size"`
UnitPrice float64 `json:"unitPrice"`
Quantity float64 `json:"quantity"`
Total float64 `json:"total"`
}
type tierBreakdown struct { type tierBreakdown struct {
UnitPrice float64 `json:"unitPrice"` UnitPrice float64 `json:"unitPrice"`
Quantity float64 `json:"quantity"` Quantity float64 `json:"quantity"`
@@ -21,9 +35,10 @@ type tierBreakdown struct {
} }
type usageResponse struct { type usageResponse struct {
Type string `json:"type"` Type string `json:"type"`
Unit string `json:"unit"` Unit string `json:"unit"`
Tiers []tierBreakdown `json:"tiers"` Tiers []tierBreakdown `json:"tiers"`
DayWiseBreakdown DayWiseBreakdown `json:"dayWiseBreakdown"`
} }
type details struct { type details struct {
@@ -40,6 +55,7 @@ type billingDetails struct {
BillingPeriodEnd int64 `json:"billingPeriodEnd"` BillingPeriodEnd int64 `json:"billingPeriodEnd"`
Details details `json:"details"` Details details `json:"details"`
Discount float64 `json:"discount"` Discount float64 `json:"discount"`
SubscriptionStatus string `json:"subscriptionStatus"`
} `json:"data"` } `json:"data"`
} }

View File

@@ -12,6 +12,7 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
"go.signoz.io/signoz/ee/query-service/model" "go.signoz.io/signoz/ee/query-service/model"
"go.signoz.io/signoz/pkg/query-service/auth" "go.signoz.io/signoz/pkg/query-service/auth"
baseconstants "go.signoz.io/signoz/pkg/query-service/constants"
basemodel "go.signoz.io/signoz/pkg/query-service/model" basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.uber.org/zap" "go.uber.org/zap"
) )
@@ -28,7 +29,7 @@ func generatePATToken() string {
func (ah *APIHandler) createPAT(w http.ResponseWriter, r *http.Request) { func (ah *APIHandler) createPAT(w http.ResponseWriter, r *http.Request) {
ctx := context.Background() ctx := context.Background()
req := model.PAT{} req := model.CreatePATRequestBody{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil { if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
RespondError(w, model.BadRequest(err), nil) RespondError(w, model.BadRequest(err), nil)
return return
@@ -41,30 +42,87 @@ func (ah *APIHandler) createPAT(w http.ResponseWriter, r *http.Request) {
}, nil) }, nil)
return return
} }
pat := model.PAT{
// All the PATs are associated with the user creating the PAT. Hence, the permissions Name: req.Name,
// associated with the PAT is also equivalent to that of the user. Role: req.Role,
req.UserID = user.Id ExpiresAt: req.ExpiresInDays,
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 err = validatePATRequest(pat)
if req.ExpiresAt > time.Now().AddDate(1, 0, 0).Unix() { if err != nil {
req.ExpiresAt = time.Now().AddDate(1, 0, 0).Unix() RespondError(w, model.BadRequest(err), nil)
return
} }
zap.S().Debugf("Got PAT request: %+v", req) // All the PATs are associated with the user creating the PAT.
pat.UserID = user.Id
pat.CreatedAt = time.Now().Unix()
pat.UpdatedAt = time.Now().Unix()
pat.LastUsed = 0
pat.Token = generatePATToken()
if pat.ExpiresAt != 0 {
// convert expiresAt to unix timestamp from days
pat.ExpiresAt = time.Now().Unix() + (pat.ExpiresAt * 24 * 60 * 60)
}
zap.S().Debugf("Got Create PAT request: %+v", pat)
var apierr basemodel.BaseApiError var apierr basemodel.BaseApiError
if req, apierr = ah.AppDao().CreatePAT(ctx, req); apierr != nil { if pat, apierr = ah.AppDao().CreatePAT(ctx, pat); apierr != nil {
RespondError(w, apierr, nil) RespondError(w, apierr, nil)
return return
} }
ah.Respond(w, &req) ah.Respond(w, &pat)
}
func validatePATRequest(req model.PAT) error {
if req.Role == "" || (req.Role != baseconstants.ViewerGroup && req.Role != baseconstants.EditorGroup && req.Role != baseconstants.AdminGroup) {
return fmt.Errorf("valid role is required")
}
if req.ExpiresAt < 0 {
return fmt.Errorf("valid expiresAt is required")
}
if req.Name == "" {
return fmt.Errorf("valid name is required")
}
return nil
}
func (ah *APIHandler) updatePAT(w http.ResponseWriter, r *http.Request) {
ctx := context.Background()
req := model.PAT{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
RespondError(w, model.BadRequest(err), nil)
return
}
user, err := auth.GetUserFromRequest(r)
if err != nil {
RespondError(w, &model.ApiError{
Typ: model.ErrorUnauthorized,
Err: err,
}, nil)
return
}
err = validatePATRequest(req)
if err != nil {
RespondError(w, model.BadRequest(err), nil)
return
}
req.UpdatedByUserID = user.Id
id := mux.Vars(r)["id"]
req.UpdatedAt = time.Now().Unix()
zap.S().Debugf("Got Update PAT request: %+v", req)
var apierr basemodel.BaseApiError
if apierr = ah.AppDao().UpdatePAT(ctx, req, id); apierr != nil {
RespondError(w, apierr, nil)
return
}
ah.Respond(w, map[string]string{"data": "pat updated successfully"})
} }
func (ah *APIHandler) getPATs(w http.ResponseWriter, r *http.Request) { func (ah *APIHandler) getPATs(w http.ResponseWriter, r *http.Request) {
@@ -78,7 +136,7 @@ func (ah *APIHandler) getPATs(w http.ResponseWriter, r *http.Request) {
return return
} }
zap.S().Infof("Get PATs for user: %+v", user.Id) zap.S().Infof("Get PATs for user: %+v", user.Id)
pats, apierr := ah.AppDao().ListPATs(ctx, user.Id) pats, apierr := ah.AppDao().ListPATs(ctx)
if apierr != nil { if apierr != nil {
RespondError(w, apierr, nil) RespondError(w, apierr, nil)
return return
@@ -86,7 +144,7 @@ func (ah *APIHandler) getPATs(w http.ResponseWriter, r *http.Request) {
ah.Respond(w, pats) ah.Respond(w, pats)
} }
func (ah *APIHandler) deletePAT(w http.ResponseWriter, r *http.Request) { func (ah *APIHandler) revokePAT(w http.ResponseWriter, r *http.Request) {
ctx := context.Background() ctx := context.Background()
id := mux.Vars(r)["id"] id := mux.Vars(r)["id"]
user, err := auth.GetUserFromRequest(r) user, err := auth.GetUserFromRequest(r)
@@ -97,22 +155,11 @@ func (ah *APIHandler) deletePAT(w http.ResponseWriter, r *http.Request) {
}, nil) }, nil)
return return
} }
pat, apierr := ah.AppDao().GetPATByID(ctx, id)
if apierr != nil { zap.S().Debugf("Revoke PAT with id: %+v", id)
if apierr := ah.AppDao().RevokePAT(ctx, id, user.Id); apierr != nil {
RespondError(w, apierr, nil) RespondError(w, apierr, nil)
return return
} }
if pat.UserID != user.Id { ah.Respond(w, map[string]string{"data": "pat revoked successfully"})
RespondError(w, &model.ApiError{
Typ: model.ErrorUnauthorized,
Err: fmt.Errorf("unauthorized PAT delete request"),
}, nil)
return
}
zap.S().Debugf("Delete PAT with id: %+v", id)
if apierr := ah.AppDao().DeletePAT(ctx, id); apierr != nil {
RespondError(w, apierr, nil)
return
}
ah.Respond(w, map[string]string{"data": "pat deleted successfully"})
} }

View File

@@ -20,10 +20,11 @@ import (
"github.com/soheilhy/cmux" "github.com/soheilhy/cmux"
"go.signoz.io/signoz/ee/query-service/app/api" "go.signoz.io/signoz/ee/query-service/app/api"
"go.signoz.io/signoz/ee/query-service/app/db" "go.signoz.io/signoz/ee/query-service/app/db"
"go.signoz.io/signoz/ee/query-service/auth"
"go.signoz.io/signoz/ee/query-service/constants" "go.signoz.io/signoz/ee/query-service/constants"
"go.signoz.io/signoz/ee/query-service/dao" "go.signoz.io/signoz/ee/query-service/dao"
"go.signoz.io/signoz/ee/query-service/interfaces" "go.signoz.io/signoz/ee/query-service/interfaces"
"go.signoz.io/signoz/pkg/query-service/auth" baseauth "go.signoz.io/signoz/pkg/query-service/auth"
baseInterface "go.signoz.io/signoz/pkg/query-service/interfaces" baseInterface "go.signoz.io/signoz/pkg/query-service/interfaces"
v3 "go.signoz.io/signoz/pkg/query-service/model/v3" v3 "go.signoz.io/signoz/pkg/query-service/model/v3"
@@ -34,10 +35,10 @@ import (
baseapp "go.signoz.io/signoz/pkg/query-service/app" baseapp "go.signoz.io/signoz/pkg/query-service/app"
"go.signoz.io/signoz/pkg/query-service/app/dashboards" "go.signoz.io/signoz/pkg/query-service/app/dashboards"
baseexplorer "go.signoz.io/signoz/pkg/query-service/app/explorer" baseexplorer "go.signoz.io/signoz/pkg/query-service/app/explorer"
"go.signoz.io/signoz/pkg/query-service/app/integrations"
"go.signoz.io/signoz/pkg/query-service/app/logparsingpipeline" "go.signoz.io/signoz/pkg/query-service/app/logparsingpipeline"
"go.signoz.io/signoz/pkg/query-service/app/opamp" "go.signoz.io/signoz/pkg/query-service/app/opamp"
opAmpModel "go.signoz.io/signoz/pkg/query-service/app/opamp/model" opAmpModel "go.signoz.io/signoz/pkg/query-service/app/opamp/model"
baseauth "go.signoz.io/signoz/pkg/query-service/auth"
"go.signoz.io/signoz/pkg/query-service/cache" "go.signoz.io/signoz/pkg/query-service/cache"
baseconst "go.signoz.io/signoz/pkg/query-service/constants" baseconst "go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/healthcheck" "go.signoz.io/signoz/pkg/query-service/healthcheck"
@@ -171,13 +172,22 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
} }
// initiate opamp // initiate opamp
_, err = opAmpModel.InitDB(baseconst.RELATIONAL_DATASOURCE_PATH) _, err = opAmpModel.InitDB(localDB)
if err != nil { if err != nil {
return nil, err return nil, err
} }
integrationsController, err := integrations.NewController(localDB)
if err != nil {
return nil, fmt.Errorf(
"couldn't create integrations controller: %w", err,
)
}
// ingestion pipelines manager // ingestion pipelines manager
logParsingPipelineController, err := logparsingpipeline.NewLogParsingPipelinesController(localDB, "sqlite") logParsingPipelineController, err := logparsingpipeline.NewLogParsingPipelinesController(
localDB, "sqlite", integrationsController.GetPipelinesForInstalledIntegrations,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -193,7 +203,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
} }
// start the usagemanager // start the usagemanager
usageManager, err := usage.New("sqlite", localDB, lm.GetRepo(), reader.GetConn()) usageManager, err := usage.New("sqlite", modelDao, lm.GetRepo(), reader.GetConn())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -233,6 +243,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
UsageManager: usageManager, UsageManager: usageManager,
FeatureFlags: lm, FeatureFlags: lm,
LicenseManager: lm, LicenseManager: lm,
IntegrationsController: integrationsController,
LogsParsingPipelineController: logParsingPipelineController, LogsParsingPipelineController: logParsingPipelineController,
Cache: c, Cache: c,
FluxInterval: fluxInterval, FluxInterval: fluxInterval,
@@ -278,6 +289,7 @@ func (s *Server) createPrivateServer(apiHandler *api.APIHandler) (*http.Server,
r := mux.NewRouter() r := mux.NewRouter()
r.Use(baseapp.LogCommentEnricher)
r.Use(setTimeoutMiddleware) r.Use(setTimeoutMiddleware)
r.Use(s.analyticsMiddleware) r.Use(s.analyticsMiddleware)
r.Use(loggingMiddlewarePrivate) r.Use(loggingMiddlewarePrivate)
@@ -304,25 +316,13 @@ func (s *Server) createPublicServer(apiHandler *api.APIHandler) (*http.Server, e
r := mux.NewRouter() r := mux.NewRouter()
// add auth middleware
getUserFromRequest := func(r *http.Request) (*basemodel.UserPayload, error) { getUserFromRequest := func(r *http.Request) (*basemodel.UserPayload, error) {
patToken := r.Header.Get("SIGNOZ-API-KEY") return auth.GetUserFromRequest(r, apiHandler)
if len(patToken) > 0 {
zap.S().Debugf("Received a non-zero length PAT token")
ctx := context.Background()
dao := apiHandler.AppDao()
user, err := dao.GetUserByPAT(ctx, patToken)
if err == nil && user != nil {
zap.S().Debugf("Found valid PAT user: %+v", user)
return user, nil
}
if err != nil {
zap.S().Debugf("Error while getting user for PAT: %+v", err)
}
}
return baseauth.GetUserFromRequest(r)
} }
am := baseapp.NewAuthMiddleware(getUserFromRequest) am := baseapp.NewAuthMiddleware(getUserFromRequest)
r.Use(baseapp.LogCommentEnricher)
r.Use(setTimeoutMiddleware) r.Use(setTimeoutMiddleware)
r.Use(s.analyticsMiddleware) r.Use(s.analyticsMiddleware)
r.Use(loggingMiddleware) r.Use(loggingMiddleware)
@@ -330,7 +330,9 @@ func (s *Server) createPublicServer(apiHandler *api.APIHandler) (*http.Server, e
apiHandler.RegisterRoutes(r, am) apiHandler.RegisterRoutes(r, am)
apiHandler.RegisterMetricsRoutes(r, am) apiHandler.RegisterMetricsRoutes(r, am)
apiHandler.RegisterLogsRoutes(r, am) apiHandler.RegisterLogsRoutes(r, am)
apiHandler.RegisterIntegrationRoutes(r, am)
apiHandler.RegisterQueryRangeV3Routes(r, am) apiHandler.RegisterQueryRangeV3Routes(r, am)
apiHandler.RegisterQueryRangeV4Routes(r, am)
c := cors.New(cors.Options{ c := cors.New(cors.Options{
AllowedOrigins: []string{"*"}, AllowedOrigins: []string{"*"},
@@ -424,7 +426,7 @@ func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface
data["queryType"] = postData.CompositeQuery.QueryType data["queryType"] = postData.CompositeQuery.QueryType
data["panelType"] = postData.CompositeQuery.PanelType data["panelType"] = postData.CompositeQuery.PanelType
signozLogsUsed, signozMetricsUsed = telemetry.GetInstance().CheckSigNozSignals(postData) signozLogsUsed, signozMetricsUsed, _ = telemetry.GetInstance().CheckSigNozSignals(postData)
} }
} }
@@ -438,7 +440,7 @@ func extractQueryRangeV3Data(path string, r *http.Request) (map[string]interface
telemetry.GetInstance().AddActiveLogsUser() telemetry.GetInstance().AddActiveLogsUser()
} }
data["dataSources"] = dataSources data["dataSources"] = dataSources
userEmail, err := auth.GetEmailFromJwt(r.Context()) userEmail, err := baseauth.GetEmailFromJwt(r.Context())
if err == nil { if err == nil {
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_QUERY_RANGE_V3, data, userEmail, true) telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_QUERY_RANGE_V3, data, userEmail, true)
} }
@@ -462,7 +464,7 @@ func getActiveLogs(path string, r *http.Request) {
func (s *Server) analyticsMiddleware(next http.Handler) http.Handler { func (s *Server) analyticsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := auth.AttachJwtToContext(r.Context(), r) ctx := baseauth.AttachJwtToContext(r.Context(), r)
r = r.WithContext(ctx) r = r.WithContext(ctx)
route := mux.CurrentRoute(r) route := mux.CurrentRoute(r)
path, _ := route.GetPathTemplate() path, _ := route.GetPathTemplate()
@@ -481,7 +483,7 @@ func (s *Server) analyticsMiddleware(next http.Handler) http.Handler {
} }
if _, ok := telemetry.EnabledPaths()[path]; ok { if _, ok := telemetry.EnabledPaths()[path]; ok {
userEmail, err := auth.GetEmailFromJwt(r.Context()) userEmail, err := baseauth.GetEmailFromJwt(r.Context())
if err == nil { if err == nil {
telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_PATH, data, userEmail) telemetry.GetInstance().SendEvent(telemetry.TELEMETRY_EVENT_PATH, data, userEmail)
} }

View File

@@ -0,0 +1,56 @@
package auth
import (
"context"
"fmt"
"net/http"
"time"
"go.signoz.io/signoz/ee/query-service/app/api"
baseauth "go.signoz.io/signoz/pkg/query-service/auth"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.signoz.io/signoz/pkg/query-service/telemetry"
"go.uber.org/zap"
)
func GetUserFromRequest(r *http.Request, apiHandler *api.APIHandler) (*basemodel.UserPayload, error) {
patToken := r.Header.Get("SIGNOZ-API-KEY")
if len(patToken) > 0 {
zap.S().Debugf("Received a non-zero length PAT token")
ctx := context.Background()
dao := apiHandler.AppDao()
pat, err := dao.GetPAT(ctx, patToken)
if err == nil && pat != nil {
zap.S().Debugf("Found valid PAT: %+v", pat)
if pat.ExpiresAt < time.Now().Unix() && pat.ExpiresAt != 0 {
zap.S().Debugf("PAT has expired: %+v", pat)
return nil, fmt.Errorf("PAT has expired")
}
group, apiErr := dao.GetGroupByName(ctx, pat.Role)
if apiErr != nil {
zap.S().Debugf("Error while getting group for PAT: %+v", apiErr)
return nil, apiErr
}
user, err := dao.GetUser(ctx, pat.UserID)
if err != nil {
zap.S().Debugf("Error while getting user for PAT: %+v", err)
return nil, err
}
telemetry.GetInstance().SetPatTokenUser()
dao.UpdatePATLastUsed(ctx, patToken, time.Now().Unix())
user.User.GroupId = group.Id
user.User.Id = pat.Id
return &basemodel.UserPayload{
User: user.User,
Role: pat.Role,
}, nil
}
if err != nil {
zap.S().Debugf("Error while getting user for PAT: %+v", err)
return nil, err
}
}
return baseauth.GetUserFromRequest(r)
}

View File

@@ -34,9 +34,11 @@ type ModelDao interface {
GetDomainByEmail(ctx context.Context, email string) (*model.OrgDomain, basemodel.BaseApiError) GetDomainByEmail(ctx context.Context, email string) (*model.OrgDomain, basemodel.BaseApiError)
CreatePAT(ctx context.Context, p model.PAT) (model.PAT, basemodel.BaseApiError) CreatePAT(ctx context.Context, p model.PAT) (model.PAT, basemodel.BaseApiError)
UpdatePAT(ctx context.Context, p model.PAT, id string) (basemodel.BaseApiError)
GetPAT(ctx context.Context, pat string) (*model.PAT, basemodel.BaseApiError) GetPAT(ctx context.Context, pat string) (*model.PAT, basemodel.BaseApiError)
UpdatePATLastUsed(ctx context.Context, pat string, lastUsed int64) basemodel.BaseApiError
GetPATByID(ctx context.Context, id 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) GetUserByPAT(ctx context.Context, token string) (*basemodel.UserPayload, basemodel.BaseApiError)
ListPATs(ctx context.Context, userID string) ([]model.PAT, basemodel.BaseApiError) ListPATs(ctx context.Context) ([]model.PAT, basemodel.BaseApiError)
DeletePAT(ctx context.Context, id string) basemodel.BaseApiError RevokePAT(ctx context.Context, id string, userID string) basemodel.BaseApiError
} }

View File

@@ -7,6 +7,7 @@ import (
basedao "go.signoz.io/signoz/pkg/query-service/dao" basedao "go.signoz.io/signoz/pkg/query-service/dao"
basedsql "go.signoz.io/signoz/pkg/query-service/dao/sqlite" basedsql "go.signoz.io/signoz/pkg/query-service/dao/sqlite"
baseint "go.signoz.io/signoz/pkg/query-service/interfaces" baseint "go.signoz.io/signoz/pkg/query-service/interfaces"
"go.uber.org/zap"
) )
type modelDao struct { type modelDao struct {
@@ -28,6 +29,41 @@ func (m *modelDao) checkFeature(key string) error {
return m.flags.CheckFeature(key) return m.flags.CheckFeature(key)
} }
func columnExists(db *sqlx.DB, tableName, columnName string) bool {
query := fmt.Sprintf("PRAGMA table_info(%s);", tableName)
rows, err := db.Query(query)
if err != nil {
zap.L().Error("Failed to query table info", zap.Error(err))
return false
}
defer rows.Close()
var (
cid int
name string
ctype string
notnull int
dflt_value *string
pk int
)
for rows.Next() {
err := rows.Scan(&cid, &name, &ctype, &notnull, &dflt_value, &pk)
if err != nil {
zap.L().Error("Failed to scan table info", zap.Error(err))
return false
}
if name == columnName {
return true
}
}
err = rows.Err()
if err != nil {
zap.L().Error("Failed to scan table info", zap.Error(err))
return false
}
return false
}
// InitDB creates and extends base model DB repository // InitDB creates and extends base model DB repository
func InitDB(dataSourceName string) (*modelDao, error) { func InitDB(dataSourceName string) (*modelDao, error) {
dao, err := basedsql.InitDB(dataSourceName) dao, err := basedsql.InitDB(dataSourceName)
@@ -51,11 +87,16 @@ func InitDB(dataSourceName string) (*modelDao, error) {
); );
CREATE TABLE IF NOT EXISTS personal_access_tokens ( CREATE TABLE IF NOT EXISTS personal_access_tokens (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
role TEXT NOT NULL,
user_id TEXT NOT NULL, user_id TEXT NOT NULL,
token TEXT NOT NULL UNIQUE, token TEXT NOT NULL UNIQUE,
name TEXT NOT NULL, name TEXT NOT NULL,
created_at INTEGER NOT NULL, created_at INTEGER NOT NULL,
expires_at INTEGER NOT NULL, expires_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
last_used INTEGER NOT NULL,
revoked BOOLEAN NOT NULL,
updated_by_user_id TEXT NOT NULL,
FOREIGN KEY(user_id) REFERENCES users(id) FOREIGN KEY(user_id) REFERENCES users(id)
); );
` `
@@ -65,6 +106,36 @@ func InitDB(dataSourceName string) (*modelDao, error) {
return nil, fmt.Errorf("error in creating tables: %v", err.Error()) return nil, fmt.Errorf("error in creating tables: %v", err.Error())
} }
if !columnExists(m.DB(), "personal_access_tokens", "role") {
_, err = m.DB().Exec("ALTER TABLE personal_access_tokens ADD COLUMN role TEXT NOT NULL DEFAULT 'ADMIN';")
if err != nil {
return nil, fmt.Errorf("error in adding column: %v", err.Error())
}
}
if !columnExists(m.DB(), "personal_access_tokens", "updated_at") {
_, err = m.DB().Exec("ALTER TABLE personal_access_tokens ADD COLUMN updated_at INTEGER NOT NULL DEFAULT 0;")
if err != nil {
return nil, fmt.Errorf("error in adding column: %v", err.Error())
}
}
if !columnExists(m.DB(), "personal_access_tokens", "last_used") {
_, err = m.DB().Exec("ALTER TABLE personal_access_tokens ADD COLUMN last_used INTEGER NOT NULL DEFAULT 0;")
if err != nil {
return nil, fmt.Errorf("error in adding column: %v", err.Error())
}
}
if !columnExists(m.DB(), "personal_access_tokens", "revoked") {
_, err = m.DB().Exec("ALTER TABLE personal_access_tokens ADD COLUMN revoked BOOLEAN NOT NULL DEFAULT FALSE;")
if err != nil {
return nil, fmt.Errorf("error in adding column: %v", err.Error())
}
}
if !columnExists(m.DB(), "personal_access_tokens", "updated_by_user_id") {
_, err = m.DB().Exec("ALTER TABLE personal_access_tokens ADD COLUMN updated_by_user_id TEXT NOT NULL DEFAULT '';")
if err != nil {
return nil, fmt.Errorf("error in adding column: %v", err.Error())
}
}
return m, nil return m, nil
} }

View File

@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"strconv" "strconv"
"time"
"go.signoz.io/signoz/ee/query-service/model" "go.signoz.io/signoz/ee/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model" basemodel "go.signoz.io/signoz/pkg/query-service/model"
@@ -12,12 +13,18 @@ import (
func (m *modelDao) CreatePAT(ctx context.Context, p model.PAT) (model.PAT, basemodel.BaseApiError) { func (m *modelDao) CreatePAT(ctx context.Context, p model.PAT) (model.PAT, basemodel.BaseApiError) {
result, err := m.DB().ExecContext(ctx, 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)", "INSERT INTO personal_access_tokens (user_id, token, role, name, created_at, expires_at, updated_at, updated_by_user_id, last_used, revoked) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
p.UserID, p.UserID,
p.Token, p.Token,
p.Role,
p.Name, p.Name,
p.CreatedAt, p.CreatedAt,
p.ExpiresAt) p.ExpiresAt,
p.UpdatedAt,
p.UpdatedByUserID,
p.LastUsed,
p.Revoked,
)
if err != nil { if err != nil {
zap.S().Errorf("Failed to insert PAT in db, err: %v", zap.Error(err)) zap.S().Errorf("Failed to insert PAT in db, err: %v", zap.Error(err))
return model.PAT{}, model.InternalError(fmt.Errorf("PAT insertion failed")) return model.PAT{}, model.InternalError(fmt.Errorf("PAT insertion failed"))
@@ -28,24 +35,102 @@ func (m *modelDao) CreatePAT(ctx context.Context, p model.PAT) (model.PAT, basem
return model.PAT{}, model.InternalError(fmt.Errorf("PAT insertion failed")) return model.PAT{}, model.InternalError(fmt.Errorf("PAT insertion failed"))
} }
p.Id = strconv.Itoa(int(id)) p.Id = strconv.Itoa(int(id))
createdByUser, _ := m.GetUser(ctx, p.UserID)
if createdByUser == nil {
p.CreatedByUser = model.User{
NotFound: true,
}
} else {
p.CreatedByUser = model.User{
Id: createdByUser.Id,
Name: createdByUser.Name,
Email: createdByUser.Email,
CreatedAt: createdByUser.CreatedAt,
ProfilePictureURL: createdByUser.ProfilePictureURL,
NotFound: false,
}
}
return p, nil return p, nil
} }
func (m *modelDao) ListPATs(ctx context.Context, userID string) ([]model.PAT, basemodel.BaseApiError) { func (m *modelDao) UpdatePAT(ctx context.Context, p model.PAT, id string) basemodel.BaseApiError {
_, err := m.DB().ExecContext(ctx,
"UPDATE personal_access_tokens SET role=$1, name=$2, updated_at=$3, updated_by_user_id=$4 WHERE id=$5 and revoked=false;",
p.Role,
p.Name,
p.UpdatedAt,
p.UpdatedByUserID,
id)
if err != nil {
zap.S().Errorf("Failed to update PAT in db, err: %v", zap.Error(err))
return model.InternalError(fmt.Errorf("PAT update failed"))
}
return nil
}
func (m *modelDao) UpdatePATLastUsed(ctx context.Context, token string, lastUsed int64) basemodel.BaseApiError {
_, err := m.DB().ExecContext(ctx,
"UPDATE personal_access_tokens SET last_used=$1 WHERE token=$2 and revoked=false;",
lastUsed,
token)
if err != nil {
zap.S().Errorf("Failed to update PAT last used in db, err: %v", zap.Error(err))
return model.InternalError(fmt.Errorf("PAT last used update failed"))
}
return nil
}
func (m *modelDao) ListPATs(ctx context.Context) ([]model.PAT, basemodel.BaseApiError) {
pats := []model.PAT{} pats := []model.PAT{}
if err := m.DB().Select(&pats, `SELECT * FROM personal_access_tokens WHERE user_id=?;`, userID); err != nil { if err := m.DB().Select(&pats, "SELECT * FROM personal_access_tokens WHERE revoked=false ORDER by updated_at DESC;"); err != nil {
zap.S().Errorf("Failed to fetch PATs for user: %s, err: %v", userID, zap.Error(err)) zap.S().Errorf("Failed to fetch PATs err: %v", zap.Error(err))
return nil, model.InternalError(fmt.Errorf("failed to fetch PATs")) return nil, model.InternalError(fmt.Errorf("failed to fetch PATs"))
} }
for i := range pats {
createdByUser, _ := m.GetUser(ctx, pats[i].UserID)
if createdByUser == nil {
pats[i].CreatedByUser = model.User{
NotFound: true,
}
} else {
pats[i].CreatedByUser = model.User{
Id: createdByUser.Id,
Name: createdByUser.Name,
Email: createdByUser.Email,
CreatedAt: createdByUser.CreatedAt,
ProfilePictureURL: createdByUser.ProfilePictureURL,
NotFound: false,
}
}
updatedByUser, _ := m.GetUser(ctx, pats[i].UpdatedByUserID)
if updatedByUser == nil {
pats[i].UpdatedByUser = model.User{
NotFound: true,
}
} else {
pats[i].UpdatedByUser = model.User{
Id: updatedByUser.Id,
Name: updatedByUser.Name,
Email: updatedByUser.Email,
CreatedAt: updatedByUser.CreatedAt,
ProfilePictureURL: updatedByUser.ProfilePictureURL,
NotFound: false,
}
}
}
return pats, nil return pats, nil
} }
func (m *modelDao) DeletePAT(ctx context.Context, id string) basemodel.BaseApiError { func (m *modelDao) RevokePAT(ctx context.Context, id string, userID string) basemodel.BaseApiError {
_, err := m.DB().ExecContext(ctx, `DELETE from personal_access_tokens where id=?;`, id) updatedAt := time.Now().Unix()
_, err := m.DB().ExecContext(ctx,
"UPDATE personal_access_tokens SET revoked=true, updated_by_user_id = $1, updated_at=$2 WHERE id=$3",
userID, updatedAt, id)
if err != nil { if err != nil {
zap.S().Errorf("Failed to delete PAT, err: %v", zap.Error(err)) zap.S().Errorf("Failed to revoke PAT in db, err: %v", zap.Error(err))
return model.InternalError(fmt.Errorf("failed to delete PAT")) return model.InternalError(fmt.Errorf("PAT revoke failed"))
} }
return nil return nil
} }
@@ -53,7 +138,7 @@ func (m *modelDao) DeletePAT(ctx context.Context, id string) basemodel.BaseApiEr
func (m *modelDao) GetPAT(ctx context.Context, token string) (*model.PAT, basemodel.BaseApiError) { func (m *modelDao) GetPAT(ctx context.Context, token string) (*model.PAT, basemodel.BaseApiError) {
pats := []model.PAT{} pats := []model.PAT{}
if err := m.DB().Select(&pats, `SELECT * FROM personal_access_tokens WHERE token=?;`, token); err != nil { if err := m.DB().Select(&pats, `SELECT * FROM personal_access_tokens WHERE token=? and revoked=false;`, token); err != nil {
return nil, model.InternalError(fmt.Errorf("failed to fetch PAT")) return nil, model.InternalError(fmt.Errorf("failed to fetch PAT"))
} }
@@ -70,7 +155,7 @@ func (m *modelDao) GetPAT(ctx context.Context, token string) (*model.PAT, basemo
func (m *modelDao) GetPATByID(ctx context.Context, id string) (*model.PAT, basemodel.BaseApiError) { func (m *modelDao) GetPATByID(ctx context.Context, id string) (*model.PAT, basemodel.BaseApiError) {
pats := []model.PAT{} pats := []model.PAT{}
if err := m.DB().Select(&pats, `SELECT * FROM personal_access_tokens WHERE id=?;`, id); err != nil { if err := m.DB().Select(&pats, `SELECT * FROM personal_access_tokens WHERE id=? and revoked=false;`, id); err != nil {
return nil, model.InternalError(fmt.Errorf("failed to fetch PAT")) return nil, model.InternalError(fmt.Errorf("failed to fetch PAT"))
} }
@@ -84,6 +169,7 @@ func (m *modelDao) GetPATByID(ctx context.Context, id string) (*model.PAT, basem
return &pats[0], nil return &pats[0], nil
} }
// deprecated
func (m *modelDao) GetUserByPAT(ctx context.Context, token string) (*basemodel.UserPayload, basemodel.BaseApiError) { func (m *modelDao) GetUserByPAT(ctx context.Context, token string) (*basemodel.UserPayload, basemodel.BaseApiError) {
users := []basemodel.UserPayload{} users := []basemodel.UserPayload{}

View File

@@ -1,10 +1,32 @@
package model package model
type PAT struct { type User struct {
Id string `json:"id" db:"id"` Id string `json:"id" db:"id"`
UserID string `json:"userId" db:"user_id"` Name string `json:"name" db:"name"`
Token string `json:"token" db:"token"` Email string `json:"email" db:"email"`
Name string `json:"name" db:"name"` CreatedAt int64 `json:"createdAt" db:"created_at"`
CreatedAt int64 `json:"createdAt" db:"created_at"` ProfilePictureURL string `json:"profilePictureURL" db:"profile_picture_url"`
ExpiresAt int64 `json:"expiresAt" db:"expires_at"` NotFound bool `json:"notFound"`
}
type CreatePATRequestBody struct {
Name string `json:"name"`
Role string `json:"role"`
ExpiresInDays int64 `json:"expiresInDays"`
}
type PAT struct {
Id string `json:"id" db:"id"`
UserID string `json:"userId" db:"user_id"`
CreatedByUser User `json:"createdByUser"`
UpdatedByUser User `json:"updatedByUser"`
Token string `json:"token" db:"token"`
Role string `json:"role" db:"role"`
Name string `json:"name" db:"name"`
CreatedAt int64 `json:"createdAt" db:"created_at"`
ExpiresAt int64 `json:"expiresAt" db:"expires_at"`
UpdatedAt int64 `json:"updatedAt" db:"updated_at"`
LastUsed int64 `json:"lastUsed" db:"last_used"`
Revoked bool `json:"revoked" db:"revoked"`
UpdatedByUserID string `json:"updatedByUserId" db:"updated_by_user_id"`
} }

View File

@@ -90,6 +90,13 @@ var BasicPlan = basemodel.FeatureSet{
UsageLimit: -1, UsageLimit: -1,
Route: "", Route: "",
}, },
basemodel.Feature{
Name: basemodel.AlertChannelEmail,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{ basemodel.Feature{
Name: basemodel.AlertChannelMsTeams, Name: basemodel.AlertChannelMsTeams,
Active: false, Active: false,
@@ -177,6 +184,13 @@ var ProPlan = basemodel.FeatureSet{
UsageLimit: -1, UsageLimit: -1,
Route: "", Route: "",
}, },
basemodel.Feature{
Name: basemodel.AlertChannelEmail,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{ basemodel.Feature{
Name: basemodel.AlertChannelMsTeams, Name: basemodel.AlertChannelMsTeams,
Active: true, Active: true,
@@ -264,6 +278,13 @@ var EnterprisePlan = basemodel.FeatureSet{
UsageLimit: -1, UsageLimit: -1,
Route: "", Route: "",
}, },
basemodel.Feature{
Name: basemodel.AlertChannelEmail,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{ basemodel.Feature{
Name: basemodel.AlertChannelMsTeams, Name: basemodel.AlertChannelMsTeams,
Active: true, Active: true,
@@ -279,17 +300,17 @@ var EnterprisePlan = basemodel.FeatureSet{
Route: "", Route: "",
}, },
basemodel.Feature{ basemodel.Feature{
Name: Onboarding, Name: Onboarding,
Active: true, Active: true,
Usage: 0, Usage: 0,
UsageLimit: -1, UsageLimit: -1,
Route: "", Route: "",
}, },
basemodel.Feature{ basemodel.Feature{
Name: ChatSupport, Name: ChatSupport,
Active: true, Active: true,
Usage: 0, Usage: 0,
UsageLimit: -1, UsageLimit: -1,
Route: "", Route: "",
}, },
} }

View File

@@ -20,6 +20,8 @@ type Usage struct {
TimeStamp time.Time `json:"timestamp"` TimeStamp time.Time `json:"timestamp"`
Count int64 `json:"count"` Count int64 `json:"count"`
Size int64 `json:"size"` Size int64 `json:"size"`
OrgName string `json:"orgName"`
TenantId string `json:"tenantId"`
} }
type UsageDB struct { type UsageDB struct {

View File

@@ -4,6 +4,8 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"os"
"regexp"
"strings" "strings"
"sync/atomic" "sync/atomic"
"time" "time"
@@ -11,10 +13,10 @@ import (
"github.com/ClickHouse/clickhouse-go/v2" "github.com/ClickHouse/clickhouse-go/v2"
"github.com/go-co-op/gocron" "github.com/go-co-op/gocron"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/jmoiron/sqlx"
"go.uber.org/zap" "go.uber.org/zap"
"go.signoz.io/signoz/ee/query-service/dao"
licenseserver "go.signoz.io/signoz/ee/query-service/integrations/signozio" licenseserver "go.signoz.io/signoz/ee/query-service/integrations/signozio"
"go.signoz.io/signoz/ee/query-service/license" "go.signoz.io/signoz/ee/query-service/license"
"go.signoz.io/signoz/ee/query-service/model" "go.signoz.io/signoz/ee/query-service/model"
@@ -38,15 +40,29 @@ type Manager struct {
licenseRepo *license.Repo licenseRepo *license.Repo
scheduler *gocron.Scheduler scheduler *gocron.Scheduler
modelDao dao.ModelDao
tenantID string
} }
func New(dbType string, db *sqlx.DB, licenseRepo *license.Repo, clickhouseConn clickhouse.Conn) (*Manager, error) { func New(dbType string, modelDao dao.ModelDao, licenseRepo *license.Repo, clickhouseConn clickhouse.Conn) (*Manager, error) {
hostNameRegex := regexp.MustCompile(`tcp://(?P<hostname>.*):`)
hostNameRegexMatches := hostNameRegex.FindStringSubmatch(os.Getenv("ClickHouseUrl"))
tenantID := ""
if len(hostNameRegexMatches) == 2 {
tenantID = hostNameRegexMatches[1]
tenantID = strings.TrimRight(tenantID, "-clickhouse")
}
m := &Manager{ m := &Manager{
// repository: repo, // repository: repo,
clickhouseConn: clickhouseConn, clickhouseConn: clickhouseConn,
licenseRepo: licenseRepo, licenseRepo: licenseRepo,
scheduler: gocron.NewScheduler(time.UTC).Every(1).Day().At("00:00"), // send usage every at 00:00 UTC scheduler: gocron.NewScheduler(time.UTC).Every(1).Day().At("00:00"), // send usage every at 00:00 UTC
modelDao: modelDao,
tenantID: tenantID,
} }
return m, nil return m, nil
} }
@@ -123,6 +139,15 @@ func (lm *Manager) UploadUsage() {
zap.S().Info("uploading usage data") zap.S().Info("uploading usage data")
orgName := ""
orgNames, orgError := lm.modelDao.GetOrgs(ctx)
if orgError != nil {
zap.S().Errorf("failed to get org data: %v", zap.Error(orgError))
}
if len(orgNames) == 1 {
orgName = orgNames[0].Name
}
usagesPayload := []model.Usage{} usagesPayload := []model.Usage{}
for _, usage := range usages { for _, usage := range usages {
usageDataBytes, err := encryption.Decrypt([]byte(usage.ExporterID[:32]), []byte(usage.Data)) usageDataBytes, err := encryption.Decrypt([]byte(usage.ExporterID[:32]), []byte(usage.Data))
@@ -142,6 +167,8 @@ func (lm *Manager) UploadUsage() {
usageData.ExporterID = usage.ExporterID usageData.ExporterID = usage.ExporterID
usageData.Type = usage.Type usageData.Type = usage.Type
usageData.Tenant = usage.Tenant usageData.Tenant = usage.Tenant
usageData.OrgName = orgName
usageData.TenantId = lm.tenantID
usagesPayload = append(usagesPayload, usageData) usagesPayload = append(usagesPayload, usageData)
} }

View File

@@ -20,9 +20,11 @@ const config: Config.InitialOptions = {
transform: { transform: {
'^.+\\.(ts|tsx)?$': 'ts-jest', '^.+\\.(ts|tsx)?$': 'ts-jest',
'^.+\\.(js|jsx)$': 'babel-jest', '^.+\\.(js|jsx)$': 'babel-jest',
'^.+\\.(css|scss|sass|less)$': 'jest-preview/transforms/css',
'^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)': 'jest-preview/transforms/file',
}, },
transformIgnorePatterns: [ transformIgnorePatterns: [
'node_modules/(?!(lodash-es|react-dnd|core-dnd|@react-dnd|dnd-core|react-dnd-html5-backend|axios)/)', 'node_modules/(?!(lodash-es|react-dnd|core-dnd|@react-dnd|dnd-core|react-dnd-html5-backend|axios|@signozhq/design-tokens|d3-interpolate|d3-color)/)',
], ],
setupFilesAfterEnv: ['<rootDir>jest.setup.ts'], setupFilesAfterEnv: ['<rootDir>jest.setup.ts'],
testPathIgnorePatterns: ['/node_modules/', '/public/'], testPathIgnorePatterns: ['/node_modules/', '/public/'],

View File

@@ -7,6 +7,7 @@
*/ */
import '@testing-library/jest-dom'; import '@testing-library/jest-dom';
import 'jest-styled-components'; import 'jest-styled-components';
import './src/styles.scss';
import { server } from './src/mocks-server/server'; import { server } from './src/mocks-server/server';
// Establish API mocking before all tests. // Establish API mocking before all tests.

View File

@@ -13,6 +13,8 @@
"jest": "jest", "jest": "jest",
"jest:coverage": "jest --coverage", "jest:coverage": "jest --coverage",
"jest:watch": "jest --watch", "jest:watch": "jest --watch",
"jest-preview": "jest-preview",
"test:debug": "npm-run-all -p test jest-preview",
"postinstall": "is-ci || yarn husky:configure", "postinstall": "is-ci || yarn husky:configure",
"playwright": "npm run i18n:generate-hash && NODE_ENV=testing playwright test --config=./playwright.config.ts", "playwright": "npm run i18n:generate-hash && NODE_ENV=testing playwright test --config=./playwright.config.ts",
"playwright:local:debug": "PWDEBUG=console yarn playwright --headed --browser=chromium", "playwright:local:debug": "PWDEBUG=console yarn playwright --headed --browser=chromium",
@@ -36,6 +38,11 @@
"@mdx-js/loader": "2.3.0", "@mdx-js/loader": "2.3.0",
"@mdx-js/react": "2.3.0", "@mdx-js/react": "2.3.0",
"@monaco-editor/react": "^4.3.1", "@monaco-editor/react": "^4.3.1",
"@radix-ui/react-tabs": "1.0.4",
"@radix-ui/react-tooltip": "1.0.7",
"@sentry/react": "7.102.1",
"@sentry/webpack-plugin": "2.14.2",
"@signozhq/design-tokens": "0.0.8",
"@uiw/react-md-editor": "3.23.5", "@uiw/react-md-editor": "3.23.5",
"@xstate/react": "^3.0.0", "@xstate/react": "^3.0.0",
"ansi-to-html": "0.7.2", "ansi-to-html": "0.7.2",
@@ -66,6 +73,7 @@
"fontfaceobserver": "2.3.0", "fontfaceobserver": "2.3.0",
"history": "4.10.1", "history": "4.10.1",
"html-webpack-plugin": "5.5.0", "html-webpack-plugin": "5.5.0",
"http-proxy-middleware": "2.0.6",
"i18next": "^21.6.12", "i18next": "^21.6.12",
"i18next-browser-languagedetector": "^6.1.3", "i18next-browser-languagedetector": "^6.1.3",
"i18next-http-backend": "^1.3.2", "i18next-http-backend": "^1.3.2",
@@ -74,11 +82,12 @@
"less": "^4.1.2", "less": "^4.1.2",
"less-loader": "^10.2.0", "less-loader": "^10.2.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"lucide-react": "0.288.0", "lucide-react": "0.321.0",
"mini-css-extract-plugin": "2.4.5", "mini-css-extract-plugin": "2.4.5",
"papaparse": "5.4.1", "papaparse": "5.4.1",
"react": "18.2.0", "react": "18.2.0",
"react-addons-update": "15.6.3", "react-addons-update": "15.6.3",
"react-beautiful-dnd": "13.1.1",
"react-dnd": "16.0.1", "react-dnd": "16.0.1",
"react-dnd-html5-backend": "16.0.1", "react-dnd-html5-backend": "16.0.1",
"react-dom": "18.2.0", "react-dom": "18.2.0",
@@ -98,6 +107,7 @@
"react-virtuoso": "4.0.3", "react-virtuoso": "4.0.3",
"redux": "^4.0.5", "redux": "^4.0.5",
"redux-thunk": "^2.3.0", "redux-thunk": "^2.3.0",
"rehype-raw": "7.0.0",
"stream": "^0.0.2", "stream": "^0.0.2",
"style-loader": "1.3.0", "style-loader": "1.3.0",
"styled-components": "^5.3.11", "styled-components": "^5.3.11",
@@ -152,6 +162,7 @@
"@types/papaparse": "5.3.7", "@types/papaparse": "5.3.7",
"@types/react": "18.0.26", "@types/react": "18.0.26",
"@types/react-addons-update": "0.14.21", "@types/react-addons-update": "0.14.21",
"@types/react-beautiful-dnd": "13.1.8",
"@types/react-dom": "18.0.10", "@types/react-dom": "18.0.10",
"@types/react-grid-layout": "^1.1.2", "@types/react-grid-layout": "^1.1.2",
"@types/react-helmet-async": "1.0.3", "@types/react-helmet-async": "1.0.3",
@@ -189,9 +200,11 @@
"husky": "^7.0.4", "husky": "^7.0.4",
"is-ci": "^3.0.1", "is-ci": "^3.0.1",
"jest-playwright-preset": "^1.7.2", "jest-playwright-preset": "^1.7.2",
"jest-preview": "0.3.1",
"jest-styled-components": "^7.0.8", "jest-styled-components": "^7.0.8",
"lint-staged": "^12.5.0", "lint-staged": "^12.5.0",
"msw": "1.3.2", "msw": "1.3.2",
"npm-run-all": "latest",
"portfinder-sync": "^0.0.2", "portfinder-sync": "^0.0.2",
"prettier": "2.2.1", "prettier": "2.2.1",
"raw-loader": "4.0.2", "raw-loader": "4.0.2",
@@ -209,7 +222,8 @@
}, },
"lint-staged": { "lint-staged": {
"*.(js|jsx|ts|tsx)": [ "*.(js|jsx|ts|tsx)": [
"eslint --fix" "eslint --fix",
"sh scripts/typecheck-staged.sh"
] ]
}, },
"resolutions": { "resolutions": {

View File

@@ -0,0 +1 @@
<svg width="32" height="33" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.91 28.675c-6.199 0-12.888-3.888-12.888-12.421S9.711 3.832 15.911 3.832c3.444 0 6.621 1.134 8.977 3.2 2.555 2.267 3.91 5.466 3.91 9.222 0 3.755-1.355 6.933-3.91 9.2-2.356 2.066-5.555 3.221-8.977 3.221z" fill="url(#prefix__paint0_radial_2122_6520)"/><path d="M26.552 8.87c1.185 1.91 1.803 4.186 1.803 6.717 0 3.756-1.356 6.933-3.911 9.2-2.356 2.066-5.556 3.222-8.978 3.222-4.013 0-8.221-1.634-10.706-5.098 2.391 3.924 6.889 5.764 11.15 5.764 3.423 0 6.623-1.155 8.978-3.222 2.555-2.266 3.911-5.444 3.911-9.2 0-2.83-.771-5.346-2.247-7.383z" fill="#EB8F00"/><path d="M20.123 22.905c0 1.685-1.846 2.667-4.124 2.667-2.277 0-4.124-.989-4.124-2.667 0-1.677 1.847-3.522 4.124-3.522 2.278 0 4.124 1.838 4.124 3.522zM12.06 14.852l1.88-1.748c.267-.331.307-.778.038-1.045-.353-.355-.98-.269-1.32.136-.018.033-.03.042-.049.075l-1.333 1.938-1.804-1.682c-.027-.03-.042-.034-.067-.062-.42-.32-1.05-.267-1.315.157-.207.32-.07.745.264 1.011l2.313 1.372-1.96 1.833c-.262.326-.31.77-.04 1.044.351.358.978.276 1.32-.127.018-.033.031-.042.051-.075l1.405-2.031 1.706 1.609c.027.029.043.035.067.064.418.322 1.049.273 1.318-.149.206-.32.07-.746-.26-1.013l-2.213-1.307zM20.61 14.852l-1.879-1.748c-.267-.331-.307-.778-.036-1.045.354-.355.978-.269 1.318.136.018.033.034.042.051.075l1.334 1.938 1.806-1.682c.025-.03.04-.034.065-.062.422-.32 1.05-.267 1.317.157.205.32.067.745-.266 1.011L22 15.004l1.96 1.833c.268.33.313.775.042 1.044-.349.358-.976.276-1.318-.127-.02-.033-.033-.042-.051-.075l-1.404-2.031-1.71 1.609c-.024.029-.04.035-.066.064-.418.322-1.046.273-1.315-.149-.21-.32-.074-.746.257-1.013l2.216-1.307zM11.911 8.696c.511.044.711-.645.178-.8a4.07 4.07 0 00-1.289-.133A4.596 4.596 0 007.689 9.14c-.378.4.156.89.556.6a5.829 5.829 0 013.666-1.044zM20.044 8.696a5.85 5.85 0 013.689 1.044c.4.29.933-.2.555-.6a4.645 4.645 0 00-3.11-1.377 4.07 4.07 0 00-1.29.133.408.408 0 00-.282.504c.053.194.24.318.438.296z" fill="#422B0D"/><defs><radialGradient id="prefix__paint0_radial_2122_6520" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(15.91 16.254) scale(12.657)"><stop offset=".5" stop-color="#FDE030"/><stop offset=".92" stop-color="#F7C02B"/><stop offset="1" stop-color="#F4A223"/></radialGradient></defs></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

@@ -0,0 +1 @@
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 2c1 2.538 2.5 2.962 3.5 3.808.942.78 1.481 1.845 1.5 2.961 0 1.122-.527 2.198-1.464 2.992C14.598 12.554 13.326 13 12 13s-2.598-.446-3.536-1.24C7.527 10.968 7 9.892 7 8.77c0-.255 0-.508.1-.762.085.25.236.48.443.673.207.193.463.342.75.437a2.334 2.334 0 001.767-.128c.263-.135.485-.32.65-.539.166-.22.269-.468.301-.727a1.452 1.452 0 00-.11-.765 1.699 1.699 0 00-.501-.644C8 4.115 11 2 12 2zM17 16l-5 6-5-6h10z" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 581 B

View File

@@ -0,0 +1 @@
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M23.06 17.526c-1.281.668-7.916 3.396-9.328 4.132-1.413.736-2.198.73-3.314.196C9.303 21.32 2.242 18.468.97 17.86c-.636-.303-.97-.56-.97-.802v-2.426s9.192-2.001 10.676-2.534c1.484-.532 1.999-.551 3.262-.089 1.263.463 8.814 1.826 10.062 2.283v2.391c0 .24-.288.503-.94.843z" fill="#912626"/><path d="M23.06 15.114c-1.281.668-7.916 3.396-9.329 4.132-1.412.737-2.197.73-3.313.196C9.302 18.91 2.242 16.056.97 15.45c-1.272-.608-1.298-1.027-.049-1.516 1.25-.49 8.271-3.244 9.755-3.776 1.484-.533 1.999-.552 3.262-.09 1.263.463 7.858 3.088 9.106 3.546 1.248.457 1.296.834.015 1.501z" fill="#C6302B"/><path d="M23.06 13.6c-1.281.668-7.916 3.396-9.328 4.133-1.413.736-2.198.73-3.314.196S2.242 14.543.97 13.935c-.636-.304-.97-.56-.97-.802v-2.426s9.192-2.001 10.676-2.534c1.484-.532 1.999-.551 3.262-.089C15.2 8.547 22.752 9.91 24 10.366v2.392c0 .24-.288.503-.94.843z" fill="#912626"/><path d="M23.06 11.19c-1.281.667-7.916 3.395-9.329 4.131-1.412.737-2.197.73-3.313.196-1.116-.533-8.176-3.386-9.448-3.993-1.272-.608-1.298-1.027-.049-1.516 1.25-.49 8.271-3.244 9.755-3.776 1.484-.533 1.999-.552 3.262-.09 1.263.463 7.858 3.088 9.106 3.545 1.248.458 1.296.835.015 1.502z" fill="#C6302B"/><path d="M23.06 9.53c-1.281.668-7.916 3.396-9.328 4.132-1.413.737-2.198.73-3.314.196-1.116-.533-8.176-3.386-9.448-3.993C.334 9.56 0 9.305 0 9.062V6.636s9.192-2 10.676-2.533c1.484-.533 1.999-.552 3.262-.09C15.2 4.477 22.752 5.84 24 6.297v2.392c0 .24-.288.502-.94.842z" fill="#912626"/><path d="M23.06 7.118c-1.281.668-7.916 3.396-9.329 4.132-1.412.737-2.197.73-3.313.196C9.303 10.913 2.242 8.061.97 7.453-.302 6.845-.328 6.427.921 5.937c1.25-.489 8.271-3.244 9.755-3.776 1.484-.532 1.999-.552 3.262-.089 1.263.463 7.858 3.088 9.106 3.545 1.248.457 1.296.834.015 1.501z" fill="#C6302B"/><path d="M14.933 4.758l-2.064.215-.462 1.111-.746-1.24L9.28 4.63l1.778-.641-.534-.985 1.665.651 1.569-.513-.424 1.017 1.6.6zm-2.649 5.393l-3.85-1.597 5.517-.847-1.667 2.444zM6.945 5.376c1.63 0 2.95.512 2.95 1.143 0 .632-1.32 1.144-2.95 1.144-1.629 0-2.95-.512-2.95-1.144 0-.63 1.321-1.143 2.95-1.143z" fill="#fff"/><path d="M17.371 5.062l3.266 1.29-3.263 1.29-.003-2.58z" fill="#621B1C"/><path d="M13.758 6.492l3.613-1.43.003 2.58-.354.139-3.262-1.29z" fill="#9A2928"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1 @@
<svg width="32" height="33" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M14.309 13.108l-6.704-3.32s-.016-.317.284-.477c.302-.16 5.053-2.107 5.435-2.107.383 0 2.62.431 4.249.793 1.629.363 5.933 1.287 5.953 1.57.02.281-4.404 4.806-4.404 4.806l-4.813-1.265z" fill="#C3FECE"/><path d="M20.423 11.037s-2.811-.826-5.546-1.469c-1.274-.3-5.016-1.084-5.016-1.084s.398-.173.698-.3c.305-.127.547-.193.547-.193s2.44.486 4.253.873c2.453.522 5.886 1.547 5.966 1.709.082.16-.902.464-.902.464z" fill="#fff"/><path d="M14.98 10.26c-.598.415-.011.666 1.09.924 1.207.282 2.127.698 2.903.247.7-.405-1.014-.845-1.8-1.014-.6-.129-1.731-.478-2.193-.158z" fill="#ACB1B2"/><path d="M17.17 11.095c-.005 0 .02-4.869.02-5.049 0-.18-.203-.342.02-.724.222-.382.804-.342.804-.342s2.416-.702 3.38-.945c.964-.242 3.098-.804 3.098-.804l.142 1.22s-2.236.631-3.342.913c-1.107.282-2.616.745-2.616.745l-.222.202.064 4.757s-.206.231-.668.231c-.45-.002-.68-.204-.68-.204z" fill="#FFD816"/><path d="M24.095 3.855c.018.38.22.616.46.616.24 0 .404-.307.369-.707-.038-.398-.296-.58-.516-.506-.22.073-.327.32-.313.597zM18.46 6.422a.209.209 0 01-.123-.038l-1.153-.769a.225.225 0 01-.063-.309.222.222 0 01.31-.062l1.153.769a.224.224 0 01.062.309.228.228 0 01-.187.1z" fill="#FEB804"/><path d="M18.636 6.235a.225.225 0 01-.178-.089c-.295-.393-.633-.84-.693-.909a.225.225 0 01-.031-.284.222.222 0 01.309-.062c.04.027.062.042.771.986.073.098.007.238-.091.312-.04.03-.04.046-.087.046z" fill="#FEB804"/><path d="M18.365 6.609c-.01 0-.022 0-.035-.003l-1.111-.175a.221.221 0 11.069-.438l1.11.176c.12.02.225.042.205.164-.016.107-.129.276-.238.276z" fill="#FEB804"/><path d="M7.596 9.764c.353 0 3.188.744 4.65 1.013 1.463.27 5.878 1.314 6.027 1.342.149.03.12 1.94.12 1.94s2.089 10.8 2.029 11.309c-.06.506-1.431 4.415-1.431 4.415s-.807.12-2.865-.478c-2.057-.598-7.488-2.089-7.817-2.506-.329-.418-.12-5.938-.298-9.338-.182-3.402-.415-7.697-.415-7.697z" fill="#79DD8A"/><path d="M24.06 27.036c.113-.375-.518-4.402-.607-8.101-.089-3.698.229-9.324.076-9.369-.154-.042-5.256 2.553-5.256 2.553s-.022 3.671.04 7.133c.08 4.48.438 10.41.676 10.53.238.12 2.302-1.035 2.924-1.372 1.102-.598 2.058-1.074 2.147-1.374z" fill="#02AB46"/><path d="M20.408 13.82l.011-2.787.914-.45.026 3.056-.422.74-.529-.56z" fill="#DBDFE1"/><path d="M12.322 14.797c-1.973-.211-3.34 1.549-3.233 3.842.127 2.709 1.91 4.704 3.842 5.102 1.93.398 3.802-.44 3.842-3.402.044-3.087-2.669-5.353-4.451-5.542z" fill="#FEFEFD"/><path d="M13.637 17.27s-.4-1.344-1.602-.986c-1.202.357-1.853 2.973.187 4.15 1.96 1.131 3.764-.944 3.133-2.288-.574-1.227-1.718-.876-1.718-.876z" fill="#EF5B44"/><path d="M13.18 15.626c-.136.049-.243.602-.1 1.13.106.396.446.939.643.903.158-.029.278-.651.13-1.173-.174-.602-.516-.918-.674-.86z" fill="#B8CF17"/><path d="M13.15 18.746c-.564-.171-1.2 1.769-.057 2.977 1.26 1.331 2.73.158 2.69-.1-.057-.358-1.044-.615-1.53-1.215-.487-.605-.774-1.562-1.102-1.662z" fill="#FD8F01"/><path d="M11.346 18.417s.113-.849-.673-.802c-.76.046-.574.944-.574.944s-.633.076-.526.778c.08.53.64.524.64.524s-.616.242-.336.945c.249.624.822.373.822.373s-.21.609.287.93c.42.272.787.043.787.043s-.023.52.557.616c.703.115 1.007-.74.507-1.136-.38-.3-.724-.067-.724-.067s.07-.166.004-.357c-.045-.125-.116-.171-.116-.171s.616-.058.516-.758c-.1-.702-.716-.616-.716-.616s.358-.286.216-.802c-.14-.518-.671-.444-.671-.444z" fill="#A281D0"/><path d="M21.04 14.595c-.511 0-2.691-2.167-2.711-2.189a.222.222 0 01.024-.313.224.224 0 01.314.022c.14.155 1.806 1.702 2.286 2 .311-.465 1.322-2.498 2.191-4.333a.224.224 0 01.296-.107.223.223 0 01.106.296c-2.142 4.526-2.353 4.586-2.466 4.617-.013.007-.027.007-.04.007z" fill="#2D802D"/></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,19 @@
<svg width="32" height="33" viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.36806 25.9481C5.93935 25.9481 3.15283 21.7098 3.15283 16.5002C3.15283 11.2907 5.94157 7.05238 9.36806 7.05238C12.7945 7.05238 15.5833 11.2907 15.5833 16.5002C15.5833 21.7098 12.7945 25.9481 9.36806 25.9481Z" fill="#FAFAFA"/>
<path d="M9.36815 7.49694C10.8414 7.49694 12.2524 8.38594 13.3391 10.0017C14.499 11.7241 15.139 14.0333 15.139 16.5003C15.139 18.9673 14.499 21.2764 13.3391 22.9989C12.2524 24.6146 10.8414 25.5036 9.36815 25.5036C7.89489 25.5036 6.48385 24.6146 5.39724 22.9989C4.23508 21.2764 3.59734 18.9673 3.59734 16.5003C3.59734 14.0333 4.23731 11.7241 5.39724 10.0017C6.48385 8.38594 7.89267 7.49694 9.36815 7.49694ZM9.36815 6.60794C5.69056 6.60794 2.7085 11.0374 2.7085 16.5003C2.7085 21.9632 5.69056 26.3926 9.36815 26.3926C13.0457 26.3926 16.0278 21.9632 16.0278 16.5003C16.0278 11.0374 13.0457 6.60794 9.36815 6.60794Z" fill="#B0BEC5"/>
<path d="M7.47266 15.5762C6.87269 15.0118 7.00602 13.8919 7.77487 13.0741C7.81486 13.0319 7.85486 12.9919 7.89708 12.9541C7.55488 12.7608 7.17934 12.6519 6.78381 12.6519C5.18611 12.6519 3.89062 14.414 3.89062 16.585C3.89062 18.756 5.18611 20.5182 6.78381 20.5182C8.3815 20.5182 9.67699 18.756 9.67699 16.585C9.67699 16.1962 9.63477 15.8184 9.55699 15.4629C8.83703 15.9806 7.97708 16.0495 7.47266 15.5762Z" fill="url(#paint0_linear_2122_5062)"/>
<path d="M22.6294 26.3932C26.3074 26.3932 29.289 21.9642 29.289 16.5008C29.289 11.0374 26.3074 6.60847 22.6294 6.60847C18.9514 6.60847 15.9697 11.0374 15.9697 16.5008C15.9697 21.9642 18.9514 26.3932 22.6294 26.3932Z" fill="#EEEEEE"/>
<path d="M22.6283 25.9493C19.2018 25.9493 16.4131 21.711 16.4131 16.5014C16.4131 11.2919 19.2018 7.05357 22.6283 7.05357C26.0548 7.05357 28.8435 11.2919 28.8435 16.5014C28.8435 21.711 26.057 25.9493 22.6283 25.9493Z" fill="#FAFAFA"/>
<path d="M22.6284 7.49816C24.1017 7.49816 25.5127 8.38716 26.5993 10.0029C27.7592 11.7254 28.3992 14.0345 28.3992 16.5015C28.3992 18.9685 27.7592 21.2777 26.5993 23.0001C25.5127 24.6159 24.1017 25.5049 22.6284 25.5049C21.1551 25.5049 19.7441 24.6159 18.6575 23.0001C17.4976 21.2777 16.8576 18.9685 16.8576 16.5015C16.8576 14.0345 17.4976 11.7254 18.6575 10.0029C19.7441 8.38716 21.1551 7.49816 22.6284 7.49816ZM22.6284 6.60916C18.9508 6.60916 15.9688 11.0386 15.9688 16.5015C15.9688 21.9644 18.9508 26.3939 22.6284 26.3939C26.306 26.3939 29.2881 21.9644 29.2881 16.5015C29.2881 11.0386 26.306 6.60916 22.6284 6.60916Z" fill="#B0BEC5"/>
<path d="M20.7339 15.5767C20.1339 15.0123 20.2672 13.8924 21.0361 13.0746C21.0761 13.0324 21.1161 12.9924 21.1583 12.9546C20.8161 12.7613 20.4406 12.6524 20.045 12.6524C18.4473 12.6524 17.1519 14.4146 17.1519 16.5856C17.1519 18.7566 18.4473 20.5187 20.045 20.5187C21.6427 20.5187 22.9382 18.7566 22.9382 16.5856C22.9382 16.1967 22.896 15.8189 22.8182 15.4634C22.1005 15.9812 21.2383 16.05 20.7339 15.5767Z" fill="url(#paint1_linear_2122_5062)"/>
<defs>
<linearGradient id="paint0_linear_2122_5062" x1="6.78232" y1="12.651" x2="6.78232" y2="20.5188" gradientUnits="userSpaceOnUse">
<stop stop-color="#424242"/>
<stop offset="1" stop-color="#212121"/>
</linearGradient>
<linearGradient id="paint1_linear_2122_5062" x1="20.0449" y1="12.6515" x2="20.0449" y2="20.5193" gradientUnits="userSpaceOnUse">
<stop stop-color="#424242"/>
<stop offset="1" stop-color="#212121"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="80px" height="80px" viewBox="0 0 80 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
<title>Icon-Architecture/64/Arch_Amazon-EC2_64</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="0%" y1="100%" x2="100%" y2="0%" id="linearGradient-1">
<stop stop-color="#C8511B" offset="0%"></stop>
<stop stop-color="#FF9900" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Icon-Architecture/64/Arch_Amazon-EC2_64" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Icon-Architecture-BG/64/Compute" fill="url(#linearGradient-1)">
<rect id="Rectangle" x="0" y="0" width="80" height="80"></rect>
</g>
<path d="M27,53 L52,53 L52,28 L27,28 L27,53 Z M54,28 L58,28 L58,30 L54,30 L54,34 L58,34 L58,36 L54,36 L54,39 L58,39 L58,41 L54,41 L54,45 L58,45 L58,47 L54,47 L54,51 L58,51 L58,53 L54,53 L54,53.136 C54,54.164 53.164,55 52.136,55 L52,55 L52,59 L50,59 L50,55 L46,55 L46,59 L44,59 L44,55 L41,55 L41,59 L39,59 L39,55 L35,55 L35,59 L33,59 L33,55 L29,55 L29,59 L27,59 L27,55 L26.864,55 C25.836,55 25,54.164 25,53.136 L25,53 L22,53 L22,51 L25,51 L25,47 L22,47 L22,45 L25,45 L25,41 L22,41 L22,39 L25,39 L25,36 L22,36 L22,34 L25,34 L25,30 L22,30 L22,28 L25,28 L25,27.864 C25,26.836 25.836,26 26.864,26 L27,26 L27,22 L29,22 L29,26 L33,26 L33,22 L35,22 L35,26 L39,26 L39,22 L41,22 L41,26 L44,26 L44,22 L46,22 L46,26 L50,26 L50,22 L52,22 L52,26 L52.136,26 C53.164,26 54,26.836 54,27.864 L54,28 Z M41,65.876 C41,65.944 40.944,66 40.876,66 L14.124,66 C14.056,66 14,65.944 14,65.876 L14,39.124 C14,39.056 14.056,39 14.124,39 L20,39 L20,37 L14.124,37 C12.953,37 12,37.953 12,39.124 L12,65.876 C12,67.047 12.953,68 14.124,68 L40.876,68 C42.047,68 43,67.047 43,65.876 L43,61 L41,61 L41,65.876 Z M68,14.124 L68,40.876 C68,42.047 67.047,43 65.876,43 L60,43 L60,41 L65.876,41 C65.944,41 66,40.944 66,40.876 L66,14.124 C66,14.056 65.944,14 65.876,14 L39.124,14 C39.056,14 39,14.056 39,14.124 L39,20 L37,20 L37,14.124 C37,12.953 37.953,12 39.124,12 L65.876,12 C67.047,12 68,12.953 68,14.124 L68,14.124 Z" id="Amazon-EC2_Icon_64_Squid" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="80px" height="80px" viewBox="0 0 80 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
<title>Icon-Architecture/64/Arch_Amazon-Elastic-Container-Service_64</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="0%" y1="100%" x2="100%" y2="0%" id="linearGradient-1">
<stop stop-color="#C8511B" offset="0%"></stop>
<stop stop-color="#FF9900" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Icon-Architecture/64/Arch_Amazon-Elastic-Container-Service_64" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Icon-Architecture-BG/64/Containers" fill="url(#linearGradient-1)">
<rect id="Rectangle" x="0" y="0" width="80" height="80"></rect>
</g>
<path d="M64,48.2340095 L56,43.4330117 L56,32.0000169 C56,31.6440171 55.812,31.3150172 55.504,31.1360173 L44,24.4260204 L44,14.7520248 L64,26.5710194 L64,48.2340095 Z M65.509,25.13902 L43.509,12.139026 C43.199,11.9560261 42.818,11.9540261 42.504,12.131026 C42.193,12.3090259 42,12.6410257 42,13.0000256 L42,25.0000201 C42,25.3550199 42.189,25.6840198 42.496,25.8640197 L54,32.5740166 L54,44.0000114 C54,44.3510113 54.185,44.6770111 54.486,44.857011 L64.486,50.8570083 C64.644,50.9520082 64.822,51 65,51 C65.17,51 65.34,50.9570082 65.493,50.8700083 C65.807,50.6930084 66,50.3600085 66,50 L66,26.0000196 C66,25.6460198 65.814,25.31902 65.509,25.13902 L65.509,25.13902 Z M40.445,66.863001 L17,54.3990067 L17,26.5710194 L37,14.7520248 L37,24.4510204 L26.463,31.1560173 C26.175,31.3400172 26,31.6580171 26,32.0000169 L26,49.0000091 C26,49.373009 26.208,49.7150088 26.538,49.8870087 L39.991,56.8870055 C40.28,57.0370055 40.624,57.0380055 40.912,56.8880055 L53.964,50.1440086 L61.996,54.9640064 L40.445,66.863001 Z M64.515,54.1420068 L54.515,48.1420095 C54.217,47.9640096 53.849,47.9520096 53.541,48.1120095 L40.455,54.8730065 L28,48.3930094 L28,32.5490167 L38.537,25.8440197 C38.825,25.6600198 39,25.3420199 39,25.0000201 L39,13.0000256 C39,12.6410257 38.808,12.3090259 38.496,12.131026 C38.184,11.9540261 37.802,11.9560261 37.491,12.139026 L15.491,25.13902 C15.187,25.31902 15,25.6460198 15,26.0000196 L15,55 C15,55.3690062 15.204,55.7090061 15.53,55.883006 L39.984,68.8830001 C40.131,68.961 40.292,69 40.453,69 C40.62,69 40.786,68.958 40.937,68.8750001 L64.484,55.875006 C64.797,55.7020061 64.993,55.3750062 65.0001416,55.0180064 C65.006,54.6600066 64.821,54.3260067 64.515,54.1420068 L64.515,54.1420068 Z" id="Amazon-Elastic-Container-Service_Icon_64_Squid" fill="#FFFFFF"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none"><path fill="url(#amazon-eks-color-16__paint0_linear_879_141)" fill-rule="evenodd" d="M6.381 10.148h.897V8.121l1.837 2.027h1.164L7.997 7.642l2.169-2.195H8.963L7.278 7.146V5.447h-.897v4.701z" clip-rule="evenodd"/><path fill="url(#amazon-eks-color-16__paint1_linear_879_141)" d="M8.532 3.803l3.186 1.81a.173.173 0 01.088.149v3.62c0 .06.033.118.088.149l2.842 1.615a.176.176 0 00.264-.15V3.947a.173.173 0 00-.088-.15L8.708.274a.176.176 0 00-.264.15v3.23c0 .062.034.119.088.15z"/><path fill="url(#amazon-eks-color-16__paint2_linear_879_141)" d="M11.273 10.288l-3.185 1.81a.178.178 0 01-.176 0l-3.63-2.062a.173.173 0 01-.088-.15V5.762c0-.062.034-.119.088-.15l3.186-1.81a.172.172 0 00.088-.15V.424a.176.176 0 00-.264-.15L1.088 3.798a.173.173 0 00-.088.15V11.7c0 .061.033.118.088.15l6.824 3.876c.054.03.122.03.176 0l6.204-3.524a.172.172 0 000-.3l-2.843-1.615a.178.178 0 00-.176 0z"/><defs><linearGradient id="amazon-eks-color-16__paint0_linear_879_141" x1="10.691" x2="8.521" y1="9.879" y2="4.634" gradientUnits="userSpaceOnUse"><stop stop-color="#426DDB"/><stop offset="1" stop-color="#3B4BDB"/></linearGradient><linearGradient id="amazon-eks-color-16__paint1_linear_879_141" x1="15.693" x2="9.546" y1="10.544" y2="-.213" gradientUnits="userSpaceOnUse"><stop stop-color="#426DDB"/><stop offset="1" stop-color="#3B4BDB"/></linearGradient><linearGradient id="amazon-eks-color-16__paint2_linear_879_141" x1="9.433" x2="2.732" y1="14.904" y2="2.88" gradientUnits="userSpaceOnUse"><stop stop-color="#2775FF"/><stop offset="1" stop-color="#188DFF"/></linearGradient></defs></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,11 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2048_2251)">
<path opacity="0.9" d="M8.02226 15.9866C3.56539 15.9866 -6.10352e-05 12.4896 -6.10352e-05 8.11832C-6.10352e-05 3.79075 3.56539 0.25 8.02226 0.25H13.0584C14.7075 0.25 15.9999 1.56139 15.9999 3.13506V8.11832C15.9999 12.4896 12.4345 15.9866 8.02226 15.9866Z" fill="#F25733"/>
<path d="M7.95919 4.71207C4.63025 4.71207 2.75514 7.46868 2.67693 7.58603C2.48413 7.87508 2.48413 8.24888 2.67707 8.53816C2.75514 8.65528 4.63025 11.4119 7.95919 11.4119C11.2881 11.4119 13.1633 8.65528 13.2414 8.53792C13.4342 8.24888 13.4342 7.87508 13.2413 7.58582C13.1632 7.46868 11.2881 4.71207 7.95919 4.71207ZM3.13771 8.23088C3.06925 8.12832 3.06925 7.99571 3.13771 7.89307C3.20059 7.79867 4.53564 5.83764 6.92256 5.36723C5.84092 5.78476 5.07127 6.83485 5.07127 8.062C5.07127 9.28912 5.84092 10.3392 6.92256 10.7567C4.53564 10.2863 3.20059 8.32528 3.13771 8.23088ZM6.62838 8.062C6.62838 8.21488 6.50443 8.3388 6.35151 8.3388C6.19859 8.3388 6.07465 8.21488 6.07465 8.062C6.07465 7.02287 6.92003 6.17748 7.95916 6.17748C8.11207 6.17748 8.23599 6.30141 8.23599 6.45434C8.23599 6.60727 8.11207 6.73119 7.95916 6.73119C7.22535 6.73119 6.62838 7.32815 6.62838 8.062ZM7.95919 8.73504C7.58803 8.73504 7.2861 8.43312 7.2861 8.062C7.2861 7.69085 7.58803 7.3889 7.95919 7.3889C8.33039 7.3889 8.63231 7.69083 8.63231 8.062C8.63231 8.43312 8.33039 8.73504 7.95919 8.73504ZM12.7806 8.23088C12.7178 8.32528 11.3827 10.2863 8.99583 10.7567C10.0775 10.3392 10.8471 9.28912 10.8471 8.062C10.8471 6.83487 10.0775 5.78477 8.99583 5.36724C11.3827 5.83768 12.7178 7.7987 12.7806 7.89307C12.8491 7.99571 12.8491 8.12832 12.7806 8.23088Z" fill="#F9F2F9"/>
</g>
<defs>
<clipPath id="clip0_2048_2251">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -62,6 +62,7 @@
"button_cancel": "No", "button_cancel": "No",
"field_promql_expr": "PromQL Expression", "field_promql_expr": "PromQL Expression",
"field_alert_name": "Alert Name", "field_alert_name": "Alert Name",
"field_notification_channel": "Notification Channel",
"field_alert_desc": "Alert Description", "field_alert_desc": "Alert Description",
"field_labels": "Labels", "field_labels": "Labels",
"field_severity": "Severity", "field_severity": "Severity",
@@ -100,7 +101,7 @@
"user_guide_ch_step3a": "Set alert severity, name and descriptions", "user_guide_ch_step3a": "Set alert severity, name and descriptions",
"user_guide_ch_step3b": "Add tags to the alert in the Label field if needed", "user_guide_ch_step3b": "Add tags to the alert in the Label field if needed",
"user_tooltip_more_help": "More details on how to create alerts", "user_tooltip_more_help": "More details on how to create alerts",
"choose_alert_type": "Choose a type for the alert:", "choose_alert_type": "Choose a type for the alert",
"metric_based_alert": "Metric based Alert", "metric_based_alert": "Metric based Alert",
"metric_based_alert_desc": "Send a notification when a condition occurs in the metric data", "metric_based_alert_desc": "Send a notification when a condition occurs in the metric data",
"log_based_alert": "Log-based Alert", "log_based_alert": "Log-based Alert",
@@ -110,5 +111,7 @@
"exceptions_based_alert": "Exceptions-based Alert", "exceptions_based_alert": "Exceptions-based Alert",
"exceptions_based_alert_desc": "Send a notification when a condition occurs in the exceptions data.", "exceptions_based_alert_desc": "Send a notification when a condition occurs in the exceptions data.",
"field_unit": "Threshold unit", "field_unit": "Threshold unit",
"text_alert_on_absent": "Send a notification if data is missing for",
"text_for": "minutes",
"selected_query_placeholder": "Select query" "selected_query_placeholder": "Select query"
} }

View File

@@ -25,5 +25,5 @@
"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_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.", "dashboard_save_changes": "Your graph built with {{queryTag}} query will be saved. Press OK to confirm.",
"your_graph_build_with": "Your graph built with", "your_graph_build_with": "Your graph built with",
"dashboar_ok_confirm": "query will be saved. Press OK to confirm." "dashboard_ok_confirm": "query will be saved. Press OK to confirm."
} }

View File

@@ -3,6 +3,7 @@
"alert_channels": "Alert Channels", "alert_channels": "Alert Channels",
"organization_settings": "Organization Settings", "organization_settings": "Organization Settings",
"ingestion_settings": "Ingestion Settings", "ingestion_settings": "Ingestion Settings",
"api_keys": "Access Tokens",
"my_settings": "My Settings", "my_settings": "My Settings",
"overview_metrics": "Overview Metrics", "overview_metrics": "Overview Metrics",
"dbcall_metrics": "Database Calls", "dbcall_metrics": "Database Calls",

View File

@@ -54,6 +54,7 @@
"field_promql_expr": "PromQL Expression", "field_promql_expr": "PromQL Expression",
"field_alert_name": "Alert Name", "field_alert_name": "Alert Name",
"field_alert_desc": "Alert Description", "field_alert_desc": "Alert Description",
"field_notification_channel": "Notification Channel",
"field_labels": "Labels", "field_labels": "Labels",
"field_severity": "Severity", "field_severity": "Severity",
"option_critical": "Critical", "option_critical": "Critical",

View File

@@ -26,6 +26,7 @@
"MY_SETTINGS": "SigNoz | My Settings", "MY_SETTINGS": "SigNoz | My Settings",
"ORG_SETTINGS": "SigNoz | Organization Settings", "ORG_SETTINGS": "SigNoz | Organization Settings",
"INGESTION_SETTINGS": "SigNoz | Ingestion Settings", "INGESTION_SETTINGS": "SigNoz | Ingestion Settings",
"API_KEYS": "SigNoz | Access Tokens",
"SOMETHING_WENT_WRONG": "SigNoz | Something Went Wrong", "SOMETHING_WENT_WRONG": "SigNoz | Something Went Wrong",
"UN_AUTHORIZED": "SigNoz | Unauthorized", "UN_AUTHORIZED": "SigNoz | Unauthorized",
"NOT_FOUND": "SigNoz | Page Not Found", "NOT_FOUND": "SigNoz | Page Not Found",

View File

@@ -63,6 +63,7 @@
"field_promql_expr": "PromQL Expression", "field_promql_expr": "PromQL Expression",
"field_alert_name": "Alert Name", "field_alert_name": "Alert Name",
"field_alert_desc": "Alert Description", "field_alert_desc": "Alert Description",
"field_notification_channel": "Notification Channel",
"field_labels": "Labels", "field_labels": "Labels",
"field_severity": "Severity", "field_severity": "Severity",
"option_critical": "Critical", "option_critical": "Critical",
@@ -100,7 +101,7 @@
"user_guide_ch_step3a": "Set alert severity, name and descriptions", "user_guide_ch_step3a": "Set alert severity, name and descriptions",
"user_guide_ch_step3b": "Add tags to the alert in the Label field if needed", "user_guide_ch_step3b": "Add tags to the alert in the Label field if needed",
"user_tooltip_more_help": "More details on how to create alerts", "user_tooltip_more_help": "More details on how to create alerts",
"choose_alert_type": "Choose a type for the alert:", "choose_alert_type": "Choose a type for the alert",
"metric_based_alert": "Metric based Alert", "metric_based_alert": "Metric based Alert",
"metric_based_alert_desc": "Send a notification when a condition occurs in the metric data", "metric_based_alert_desc": "Send a notification when a condition occurs in the metric data",
"log_based_alert": "Log-based Alert", "log_based_alert": "Log-based Alert",
@@ -110,5 +111,7 @@
"exceptions_based_alert": "Exceptions-based Alert", "exceptions_based_alert": "Exceptions-based Alert",
"exceptions_based_alert_desc": "Send a notification when a condition occurs in the exceptions data.", "exceptions_based_alert_desc": "Send a notification when a condition occurs in the exceptions data.",
"field_unit": "Threshold unit", "field_unit": "Threshold unit",
"text_alert_on_absent": "Send a notification if data is missing for",
"text_for": "minutes",
"selected_query_placeholder": "Select query" "selected_query_placeholder": "Select query"
} }

View File

@@ -0,0 +1,3 @@
{
"delete_confirm_message": "Are you sure you want to delete {{keyName}} token? Deleting a token is irreversible and cannot be undone."
}

View File

@@ -23,6 +23,12 @@
"field_opsgenie_api_key": "API Key", "field_opsgenie_api_key": "API Key",
"field_opsgenie_description": "Description", "field_opsgenie_description": "Description",
"placeholder_opsgenie_description": "Description", "placeholder_opsgenie_description": "Description",
"help_email_to": "Email address(es) to send alerts to (comma separated)",
"field_email_to": "To",
"placeholder_email_to": "To",
"help_email_html": "Send email in html format",
"field_email_html": "Email body template",
"placeholder_email_html": "Email body template",
"field_webhook_username": "User Name (optional)", "field_webhook_username": "User Name (optional)",
"field_webhook_password": "Password (optional)", "field_webhook_password": "Password (optional)",
"field_pager_routing_key": "Routing Key", "field_pager_routing_key": "Routing Key",

View File

@@ -28,5 +28,5 @@
"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_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.", "dashboard_save_changes": "Your graph built with {{queryTag}} query will be saved. Press OK to confirm.",
"your_graph_build_with": "Your graph built with", "your_graph_build_with": "Your graph built with",
"dashboar_ok_confirm": "query will be saved. Press OK to confirm." "dashboard_ok_confirm": "query will be saved. Press OK to confirm."
} }

View File

@@ -1,3 +1,4 @@
{ {
"name_of_the_view": "Name of the view" "name_of_the_view": "Name of the view",
"delete_confirm_message": "Are you sure you want to delete {{viewName}} view? Deleting a view is irreversible and cannot be undone."
} }

View File

@@ -3,6 +3,7 @@
"alert_channels": "Alert Channels", "alert_channels": "Alert Channels",
"organization_settings": "Organization Settings", "organization_settings": "Organization Settings",
"ingestion_settings": "Ingestion Settings", "ingestion_settings": "Ingestion Settings",
"api_keys": "Access Tokens",
"my_settings": "My Settings", "my_settings": "My Settings",
"overview_metrics": "Overview Metrics", "overview_metrics": "Overview Metrics",
"dbcall_metrics": "Database Calls", "dbcall_metrics": "Database Calls",

View File

@@ -54,6 +54,7 @@
"field_promql_expr": "PromQL Expression", "field_promql_expr": "PromQL Expression",
"field_alert_name": "Alert Name", "field_alert_name": "Alert Name",
"field_alert_desc": "Alert Description", "field_alert_desc": "Alert Description",
"field_notification_channel": "Notification Channel",
"field_labels": "Labels", "field_labels": "Labels",
"field_severity": "Severity", "field_severity": "Severity",
"option_critical": "Critical", "option_critical": "Critical",

View File

@@ -4,6 +4,10 @@
"SERVICE_METRICS": "SigNoz | Service Metrics", "SERVICE_METRICS": "SigNoz | Service Metrics",
"SERVICE_MAP": "SigNoz | Service Map", "SERVICE_MAP": "SigNoz | Service Map",
"GET_STARTED": "SigNoz | Get Started", "GET_STARTED": "SigNoz | Get Started",
"GET_STARTED_APPLICATION_MONITORING": "SigNoz | Get Started | APM",
"GET_STARTED_LOGS_MANAGEMENT": "SigNoz | Get Started | Logs",
"GET_STARTED_INFRASTRUCTURE_MONITORING": "SigNoz | Get Started | Infrastructure",
"GET_STARTED_AWS_MONITORING": "SigNoz | Get Started | AWS",
"TRACE": "SigNoz | Trace", "TRACE": "SigNoz | Trace",
"TRACE_DETAIL": "SigNoz | Trace Detail", "TRACE_DETAIL": "SigNoz | Trace Detail",
"TRACES_EXPLORER": "SigNoz | Traces Explorer", "TRACES_EXPLORER": "SigNoz | Traces Explorer",
@@ -26,11 +30,13 @@
"MY_SETTINGS": "SigNoz | My Settings", "MY_SETTINGS": "SigNoz | My Settings",
"ORG_SETTINGS": "SigNoz | Organization Settings", "ORG_SETTINGS": "SigNoz | Organization Settings",
"INGESTION_SETTINGS": "SigNoz | Ingestion Settings", "INGESTION_SETTINGS": "SigNoz | Ingestion Settings",
"API_KEYS": "SigNoz | Access Tokens",
"SOMETHING_WENT_WRONG": "SigNoz | Something Went Wrong", "SOMETHING_WENT_WRONG": "SigNoz | Something Went Wrong",
"UN_AUTHORIZED": "SigNoz | Unauthorized", "UN_AUTHORIZED": "SigNoz | Unauthorized",
"NOT_FOUND": "SigNoz | Page Not Found", "NOT_FOUND": "SigNoz | Page Not Found",
"LOGS": "SigNoz | Logs", "LOGS": "SigNoz | Logs",
"LOGS_EXPLORER": "SigNoz | Logs Explorer", "LOGS_EXPLORER": "SigNoz | Logs Explorer",
"OLD_LOGS_EXPLORER": "SigNoz | Old Logs Explorer",
"LIVE_LOGS": "SigNoz | Live Logs", "LIVE_LOGS": "SigNoz | Live Logs",
"LOGS_PIPELINES": "SigNoz | Logs Pipelines", "LOGS_PIPELINES": "SigNoz | Logs Pipelines",
"HOME_PAGE": "Open source Observability Platform | SigNoz", "HOME_PAGE": "Open source Observability Platform | SigNoz",
@@ -38,5 +44,9 @@
"LIST_LICENSES": "SigNoz | List of Licenses", "LIST_LICENSES": "SigNoz | List of Licenses",
"WORKSPACE_LOCKED": "SigNoz | Workspace Locked", "WORKSPACE_LOCKED": "SigNoz | Workspace Locked",
"SUPPORT": "SigNoz | Support", "SUPPORT": "SigNoz | Support",
"DEFAULT": "Open source Observability Platform | SigNoz" "LOGS_SAVE_VIEWS": "SigNoz | Logs Saved Views",
"TRACES_SAVE_VIEWS": "SigNoz | Traces Saved Views",
"DEFAULT": "Open source Observability Platform | SigNoz",
"SHORTCUTS": "SigNoz | Shortcuts",
"INTEGRATIONS_INSTALLED": "SigNoz | Integrations"
} }

View File

@@ -0,0 +1,25 @@
files="";
# lint-staged will pass all files in $1 $2 $3 etc. iterate and concat.
for var in "$@"
do
files="$files \"$var\","
done
# create temporary tsconfig which includes only passed files
str="{
\"extends\": \"./tsconfig.json\",
\"include\": [ \"src/typings/**/*.ts\",\"src/**/*.d.ts\", \"./babel.config.js\", \"./jest.config.ts\", \"./.eslintrc.js\",\"./__mocks__\",\"./conf/default.conf\",\"./public\",\"./tests\",\"./playwright.config.ts\",\"./commitlint.config.ts\",\"./webpack.config.js\",\"./webpack.config.prod.js\",\"./jest.setup.ts\",\"./**/*.d.ts\",$files]
}"
echo $str > tsconfig.tmp
# run typecheck using temp config
tsc -p ./tsconfig.tmp
# capture exit code of tsc
code=$?
# delete temp config
rm ./tsconfig.tmp
exit $code

View File

@@ -20,16 +20,21 @@ import { UPDATE_USER_IS_FETCH } from 'types/actions/app';
import AppReducer from 'types/reducer/app'; import AppReducer from 'types/reducer/app';
import { routePermission } from 'utils/permission'; import { routePermission } from 'utils/permission';
import routes from './routes'; import routes, {
LIST_LICENSES,
oldNewRoutesMapping,
oldRoutes,
} from './routes';
import afterLogin from './utils'; import afterLogin from './utils';
function PrivateRoute({ children }: PrivateRouteProps): JSX.Element { function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
const { pathname } = useLocation(); const location = useLocation();
const { pathname } = location;
const mapRoutes = useMemo( const mapRoutes = useMemo(
() => () =>
new Map( new Map(
routes.map((e) => { [...routes, LIST_LICENSES].map((e) => {
const currentPath = matchPath(pathname, { const currentPath = matchPath(pathname, {
path: e.path, path: e.path,
}); });
@@ -59,6 +64,8 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
const currentRoute = mapRoutes.get('current'); const currentRoute = mapRoutes.get('current');
const isOldRoute = oldRoutes.indexOf(pathname) > -1;
const isLocalStorageLoggedIn = const isLocalStorageLoggedIn =
getLocalStorageApi(LOCALSTORAGE.IS_LOGGED_IN) === 'true'; getLocalStorageApi(LOCALSTORAGE.IS_LOGGED_IN) === 'true';
@@ -98,6 +105,7 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
if ( if (
userResponse && userResponse &&
route &&
route.find((e) => e === userResponse.payload.role) === undefined route.find((e) => e === userResponse.payload.role) === undefined
) { ) {
history.push(ROUTES.UN_AUTHORIZED); history.push(ROUTES.UN_AUTHORIZED);
@@ -157,10 +165,20 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
useEffect(() => { useEffect(() => {
(async (): Promise<void> => { (async (): Promise<void> => {
try { try {
if (isOldRoute) {
const redirectUrl = oldNewRoutesMapping[pathname];
const newLocation = {
...location,
pathname: redirectUrl,
};
history.replace(newLocation);
}
if (currentRoute) { if (currentRoute) {
const { isPrivate, key } = currentRoute; const { isPrivate, key } = currentRoute;
if (isPrivate && key !== ROUTES.WORKSPACE_LOCKED) { if (isPrivate && key !== String(ROUTES.WORKSPACE_LOCKED)) {
handlePrivateRoutes(key); handlePrivateRoutes(key);
} else { } else {
// no need to fetch the user and make user fetching false // no need to fetch the user and make user fetching false

View File

@@ -8,6 +8,7 @@ import { LOCALSTORAGE } from 'constants/localStorage';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import AppLayout from 'container/AppLayout'; import AppLayout from 'container/AppLayout';
import useAnalytics from 'hooks/analytics/useAnalytics'; import useAnalytics from 'hooks/analytics/useAnalytics';
import { KeyboardHotkeysProvider } from 'hooks/hotkeys/useKeyboardHotkeys';
import { useThemeConfig } from 'hooks/useDarkMode'; import { useThemeConfig } from 'hooks/useDarkMode';
import useGetFeatureFlag from 'hooks/useGetFeatureFlag'; import useGetFeatureFlag from 'hooks/useGetFeatureFlag';
import useLicense, { LICENSE_PLAN_KEY } from 'hooks/useLicense'; import useLicense, { LICENSE_PLAN_KEY } from 'hooks/useLicense';
@@ -28,7 +29,11 @@ import AppReducer, { User } from 'types/reducer/app';
import { extractDomain, isCloudUser, isEECloudUser } from 'utils/app'; import { extractDomain, isCloudUser, isEECloudUser } from 'utils/app';
import PrivateRoute from './Private'; import PrivateRoute from './Private';
import defaultRoutes, { AppRoutes, SUPPORT_ROUTE } from './routes'; import defaultRoutes, {
AppRoutes,
LIST_LICENSES,
SUPPORT_ROUTE,
} from './routes';
function App(): JSX.Element { function App(): JSX.Element {
const themeConfig = useThemeConfig(); const themeConfig = useThemeConfig();
@@ -150,6 +155,10 @@ function App(): JSX.Element {
if (isCloudUserVal || isEECloudUser()) { if (isCloudUserVal || isEECloudUser()) {
const newRoutes = [...routes, SUPPORT_ROUTE]; const newRoutes = [...routes, SUPPORT_ROUTE];
setRoutes(newRoutes);
} else {
const newRoutes = [...routes, LIST_LICENSES];
setRoutes(newRoutes); setRoutes(newRoutes);
} }
@@ -169,22 +178,24 @@ function App(): JSX.Element {
<ResourceProvider> <ResourceProvider>
<QueryBuilderProvider> <QueryBuilderProvider>
<DashboardProvider> <DashboardProvider>
<AppLayout> <KeyboardHotkeysProvider>
<Suspense fallback={<Spinner size="large" tip="Loading..." />}> <AppLayout>
<Switch> <Suspense fallback={<Spinner size="large" tip="Loading..." />}>
{routes.map(({ path, component, exact }) => ( <Switch>
<Route {routes.map(({ path, component, exact }) => (
key={`${path}`} <Route
exact={exact} key={`${path}`}
path={path} exact={exact}
component={component} path={path}
/> component={component}
))} />
))}
<Route path="*" component={NotFound} /> <Route path="*" component={NotFound} />
</Switch> </Switch>
</Suspense> </Suspense>
</AppLayout> </AppLayout>
</KeyboardHotkeysProvider>
</DashboardProvider> </DashboardProvider>
</QueryBuilderProvider> </QueryBuilderProvider>
</ResourceProvider> </ResourceProvider>

View File

@@ -15,9 +15,20 @@ export const ServiceMapPage = Loadable(
() => import(/* webpackChunkName: "ServiceMapPage" */ 'modules/Servicemap'), () => import(/* webpackChunkName: "ServiceMapPage" */ 'modules/Servicemap'),
); );
export const LogsSaveViews = Loadable(
() => import(/* webpackChunkName: "LogsSaveViews" */ 'pages/LogsModulePage'), // TODO: Add a wrapper so that the same component can be used in traces
);
export const TracesExplorer = Loadable( export const TracesExplorer = Loadable(
() => () =>
import(/* webpackChunkName: "Traces Explorer Page" */ 'pages/TracesExplorer'), import(
/* webpackChunkName: "Traces Explorer Page" */ 'pages/TracesModulePage'
),
);
export const TracesSaveViews = Loadable(
() =>
import(/* webpackChunkName: "Traces Save Views" */ 'pages/TracesModulePage'),
); );
export const TraceFilter = Loadable( export const TraceFilter = Loadable(
@@ -107,22 +118,34 @@ export const IngestionSettings = Loadable(
() => import(/* webpackChunkName: "Ingestion Settings" */ 'pages/Settings'), () => import(/* webpackChunkName: "Ingestion Settings" */ 'pages/Settings'),
); );
export const APIKeys = Loadable(
() => import(/* webpackChunkName: "All Settings" */ 'pages/Settings'),
);
export const MySettings = Loadable( export const MySettings = Loadable(
() => import(/* webpackChunkName: "All MySettings" */ 'pages/MySettings'), () => import(/* webpackChunkName: "All MySettings" */ 'pages/MySettings'),
); );
export const Logs = Loadable( export const Logs = Loadable(
() => import(/* webpackChunkName: "Logs" */ 'pages/Logs'), () => import(/* webpackChunkName: "Logs" */ 'pages/LogsModulePage'),
); );
export const LogsExplorer = Loadable( export const LogsExplorer = Loadable(
() => import(/* webpackChunkName: "Logs Explorer" */ 'pages/LogsExplorer'), () => import(/* webpackChunkName: "Logs Explorer" */ 'pages/LogsModulePage'),
);
export const OldLogsExplorer = Loadable(
() => import(/* webpackChunkName: "Logs Explorer" */ 'pages/Logs'),
); );
export const LiveLogs = Loadable( export const LiveLogs = Loadable(
() => import(/* webpackChunkName: "Live Logs" */ 'pages/LiveLogs'), () => import(/* webpackChunkName: "Live Logs" */ 'pages/LiveLogs'),
); );
export const PipelinePage = Loadable(
() => import(/* webpackChunkName: "Pipelines" */ 'pages/LogsModulePage'),
);
export const Login = Loadable( export const Login = Loadable(
() => import(/* webpackChunkName: "Login" */ 'pages/Login'), () => import(/* webpackChunkName: "Login" */ 'pages/Login'),
); );
@@ -151,10 +174,6 @@ export const LogsIndexToFields = Loadable(
import(/* webpackChunkName: "LogsIndexToFields Page" */ 'pages/LogsSettings'), import(/* webpackChunkName: "LogsIndexToFields Page" */ 'pages/LogsSettings'),
); );
export const PipelinePage = Loadable(
() => import(/* webpackChunkName: "Pipelines" */ 'pages/Pipelines'),
);
export const BillingPage = Loadable( export const BillingPage = Loadable(
() => import(/* webpackChunkName: "BillingPage" */ 'pages/Billing'), () => import(/* webpackChunkName: "BillingPage" */ 'pages/Billing'),
); );
@@ -167,3 +186,22 @@ export const WorkspaceBlocked = Loadable(
() => () =>
import(/* webpackChunkName: "WorkspaceLocked" */ 'pages/WorkspaceLocked'), import(/* webpackChunkName: "WorkspaceLocked" */ 'pages/WorkspaceLocked'),
); );
export const ShortcutsPage = Loadable(
() => import(/* webpackChunkName: "ShortcutsPage" */ 'pages/Shortcuts'),
);
export const InstalledIntegrations = Loadable(
() =>
import(
/* webpackChunkName: "InstalledIntegrations" */ 'pages/IntegrationsModulePage'
),
);
export const IntegrationsMarketPlace = Loadable(
// eslint-disable-next-line sonarjs/no-identical-functions
() =>
import(
/* webpackChunkName: "IntegrationsMarketPlace" */ 'pages/IntegrationsModulePage'
),
);

View File

@@ -1,10 +1,10 @@
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import WorkspaceBlocked from 'pages/WorkspaceLocked';
import { RouteProps } from 'react-router-dom'; import { RouteProps } from 'react-router-dom';
import { import {
AllAlertChannels, AllAlertChannels,
AllErrors, AllErrors,
APIKeys,
BillingPage, BillingPage,
CreateAlertChannelAlerts, CreateAlertChannelAlerts,
CreateNewAlerts, CreateNewAlerts,
@@ -14,6 +14,8 @@ import {
EditRulesPage, EditRulesPage,
ErrorDetails, ErrorDetails,
IngestionSettings, IngestionSettings,
InstalledIntegrations,
IntegrationsMarketPlace,
LicensePage, LicensePage,
ListAllALertsPage, ListAllALertsPage,
LiveLogs, LiveLogs,
@@ -21,8 +23,10 @@ import {
Logs, Logs,
LogsExplorer, LogsExplorer,
LogsIndexToFields, LogsIndexToFields,
LogsSaveViews,
MySettings, MySettings,
NewDashboardPage, NewDashboardPage,
OldLogsExplorer,
Onboarding, Onboarding,
OrganizationSettings, OrganizationSettings,
PasswordReset, PasswordReset,
@@ -31,6 +35,7 @@ import {
ServiceMetricsPage, ServiceMetricsPage,
ServicesTablePage, ServicesTablePage,
SettingsPage, SettingsPage,
ShortcutsPage,
SignupPage, SignupPage,
SomethingWentWrong, SomethingWentWrong,
StatusPage, StatusPage,
@@ -38,8 +43,10 @@ import {
TraceDetail, TraceDetail,
TraceFilter, TraceFilter,
TracesExplorer, TracesExplorer,
TracesSaveViews,
UnAuthorized, UnAuthorized,
UsageExplorerPage, UsageExplorerPage,
WorkspaceBlocked,
} from './pageComponents'; } from './pageComponents';
const routes: AppRoutes[] = [ const routes: AppRoutes[] = [
@@ -52,7 +59,7 @@ const routes: AppRoutes[] = [
}, },
{ {
path: ROUTES.GET_STARTED, path: ROUTES.GET_STARTED,
exact: true, exact: false,
component: Onboarding, component: Onboarding,
isPrivate: true, isPrivate: true,
key: 'GET_STARTED', key: 'GET_STARTED',
@@ -85,6 +92,13 @@ const routes: AppRoutes[] = [
exact: true, exact: true,
key: 'SERVICE_MAP', key: 'SERVICE_MAP',
}, },
{
path: ROUTES.LOGS_SAVE_VIEWS,
component: LogsSaveViews,
isPrivate: true,
exact: true,
key: 'LOGS_SAVE_VIEWS',
},
{ {
path: ROUTES.TRACE_DETAIL, path: ROUTES.TRACE_DETAIL,
exact: true, exact: true,
@@ -162,6 +176,13 @@ const routes: AppRoutes[] = [
isPrivate: true, isPrivate: true,
key: 'TRACES_EXPLORER', key: 'TRACES_EXPLORER',
}, },
{
path: ROUTES.TRACES_SAVE_VIEWS,
exact: true,
component: TracesSaveViews,
isPrivate: true,
key: 'TRACES_SAVE_VIEWS',
},
{ {
path: ROUTES.CHANNELS_NEW, path: ROUTES.CHANNELS_NEW,
exact: true, exact: true,
@@ -190,13 +211,6 @@ const routes: AppRoutes[] = [
component: AllErrors, component: AllErrors,
key: 'ALL_ERROR', key: 'ALL_ERROR',
}, },
{
path: ROUTES.LIST_LICENSES,
exact: true,
component: LicensePage,
isPrivate: true,
key: 'LIST_LICENSES',
},
{ {
path: ROUTES.ERROR_DETAIL, path: ROUTES.ERROR_DETAIL,
exact: true, exact: true,
@@ -225,6 +239,13 @@ const routes: AppRoutes[] = [
isPrivate: true, isPrivate: true,
key: 'INGESTION_SETTINGS', key: 'INGESTION_SETTINGS',
}, },
{
path: ROUTES.API_KEYS,
exact: true,
component: APIKeys,
isPrivate: true,
key: 'API_KEYS',
},
{ {
path: ROUTES.MY_SETTINGS, path: ROUTES.MY_SETTINGS,
exact: true, exact: true,
@@ -246,6 +267,13 @@ const routes: AppRoutes[] = [
key: 'LOGS_EXPLORER', key: 'LOGS_EXPLORER',
isPrivate: true, isPrivate: true,
}, },
{
path: ROUTES.OLD_LOGS_EXPLORER,
exact: true,
component: OldLogsExplorer,
key: 'OLD_LOGS_EXPLORER',
isPrivate: true,
},
{ {
path: ROUTES.LIVE_LOGS, path: ROUTES.LIVE_LOGS,
exact: true, exact: true,
@@ -253,6 +281,13 @@ const routes: AppRoutes[] = [
key: 'LIVE_LOGS', key: 'LIVE_LOGS',
isPrivate: true, isPrivate: true,
}, },
{
path: ROUTES.LOGS_PIPELINES,
exact: true,
component: PipelinePage,
key: 'LOGS_PIPELINES',
isPrivate: true,
},
{ {
path: ROUTES.LOGIN, path: ROUTES.LOGIN,
exact: true, exact: true,
@@ -281,13 +316,6 @@ const routes: AppRoutes[] = [
key: 'SOMETHING_WENT_WRONG', key: 'SOMETHING_WENT_WRONG',
isPrivate: false, isPrivate: false,
}, },
{
path: ROUTES.LOGS_PIPELINES,
exact: true,
component: PipelinePage,
key: 'LOGS_PIPELINES',
isPrivate: true,
},
{ {
path: ROUTES.BILLING, path: ROUTES.BILLING,
exact: true, exact: true,
@@ -302,6 +330,27 @@ const routes: AppRoutes[] = [
isPrivate: true, isPrivate: true,
key: 'WORKSPACE_LOCKED', key: 'WORKSPACE_LOCKED',
}, },
{
path: ROUTES.SHORTCUTS,
exact: true,
component: ShortcutsPage,
isPrivate: true,
key: 'SHORTCUTS',
},
{
path: ROUTES.INTEGRATIONS_INSTALLED,
exact: true,
component: InstalledIntegrations,
isPrivate: true,
key: 'INTEGRATIONS_INSTALLED',
},
{
path: ROUTES.INTEGRATIONS_MARKETPLACE,
exact: true,
component: IntegrationsMarketPlace,
isPrivate: true,
key: 'INTEGRATIONS_MARKETPLACE',
},
]; ];
export const SUPPORT_ROUTE: AppRoutes = { export const SUPPORT_ROUTE: AppRoutes = {
@@ -312,6 +361,34 @@ export const SUPPORT_ROUTE: AppRoutes = {
isPrivate: true, isPrivate: true,
}; };
export const LIST_LICENSES: AppRoutes = {
path: ROUTES.LIST_LICENSES,
exact: true,
component: LicensePage,
isPrivate: true,
key: 'LIST_LICENSES',
};
export const oldRoutes = [
'/pipelines',
'/logs/old-logs-explorer',
'/logs-explorer',
'/logs-explorer/live',
'/logs-save-views',
'/traces-save-views',
'/settings/api-keys',
];
export const oldNewRoutesMapping: Record<string, string> = {
'/pipelines': '/logs/pipelines',
'/logs/old-logs-explorer': '/logs/old-logs-explorer',
'/logs-explorer': '/logs/logs-explorer',
'/logs-explorer/live': '/logs/logs-explorer/live',
'/logs-save-views': '/logs/saved-views',
'/traces-save-views': '/traces/saved-views',
'/settings/api-keys': '/settings/access-tokens',
};
export interface AppRoutes { export interface AppRoutes {
component: RouteProps['component']; component: RouteProps['component'];
path: RouteProps['path']; path: RouteProps['path'];

View File

@@ -0,0 +1,26 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { APIKeyProps, CreateAPIKeyProps } from 'types/api/pat/types';
const createAPIKey = async (
props: CreateAPIKeyProps,
): Promise<SuccessResponse<APIKeyProps> | ErrorResponse> => {
try {
const response = await axios.post('/pats', {
...props,
});
return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default createAPIKey;

View File

@@ -0,0 +1,24 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { AllAPIKeyProps } from 'types/api/pat/types';
const deleteAPIKey = async (
id: string,
): Promise<SuccessResponse<AllAPIKeyProps> | ErrorResponse> => {
try {
const response = await axios.delete(`/pats/${id}`);
return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default deleteAPIKey;

View File

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

View File

@@ -0,0 +1,6 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
import { AllAPIKeyProps } from 'types/api/pat/types';
export const getAllAPIKeys = (): Promise<AxiosResponse<AllAPIKeyProps>> =>
axios.get(`/pats`);

View File

@@ -0,0 +1,26 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, UpdateAPIKeyProps } from 'types/api/pat/types';
const updateAPIKey = async (
props: UpdateAPIKeyProps,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
const response = await axios.put(`/pats/${props.id}`, {
...props.data,
});
return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default updateAPIKey;

View File

@@ -0,0 +1,7 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
import { AllIntegrationsProps } from 'types/api/integrations/types';
export const getAllIntegrations = (): Promise<
AxiosResponse<AllIntegrationsProps>
> => axios.get(`/integrations`);

View File

@@ -0,0 +1,11 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
import {
GetIntegrationPayloadProps,
GetIntegrationProps,
} from 'types/api/integrations/types';
export const getIntegration = (
props: GetIntegrationPayloadProps,
): Promise<AxiosResponse<GetIntegrationProps>> =>
axios.get(`/integrations/${props.integrationId}`);

View File

@@ -0,0 +1,11 @@
import axios from 'api';
import { AxiosResponse } from 'axios';
import {
GetIntegrationPayloadProps,
GetIntegrationStatusProps,
} from 'types/api/integrations/types';
export const getIntegrationStatus = (
props: GetIntegrationPayloadProps,
): Promise<AxiosResponse<GetIntegrationStatusProps>> =>
axios.get(`/integrations/${props.integrationId}/connection_status`);

View File

@@ -0,0 +1,31 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
InstalledIntegrationsSuccessResponse,
InstallIntegrationKeyProps,
} from 'types/api/integrations/types';
const installIntegration = async (
props: InstallIntegrationKeyProps,
): Promise<
SuccessResponse<InstalledIntegrationsSuccessResponse> | ErrorResponse
> => {
try {
const response = await axios.post('/integrations/install', {
...props,
});
return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default installIntegration;

View File

@@ -0,0 +1,31 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
UninstallIntegrationProps,
UninstallIntegrationSuccessResponse,
} from 'types/api/integrations/types';
const unInstallIntegration = async (
props: UninstallIntegrationProps,
): Promise<
SuccessResponse<UninstallIntegrationSuccessResponse> | ErrorResponse
> => {
try {
const response = await axios.post('/integrations/uninstall', {
...props,
});
return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default unInstallIntegration;

View File

@@ -2,6 +2,7 @@ const apiV1 = '/api/v1/';
export const apiV2 = '/api/v2/'; export const apiV2 = '/api/v2/';
export const apiV3 = '/api/v3/'; export const apiV3 = '/api/v3/';
export const apiV4 = '/api/v4/';
export const apiAlertManager = '/api/alertmanager'; export const apiAlertManager = '/api/alertmanager';
export default apiV1; export default apiV1;

View File

@@ -0,0 +1,34 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/createEmail';
const create = async (
props: Props,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
const response = await axios.post('/channels', {
name: props.name,
email_configs: [
{
send_resolved: true,
to: props.to,
html: props.html,
headers: props.headers,
},
],
});
return {
statusCode: 200,
error: null,
message: 'Success',
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default create;

View File

@@ -0,0 +1,34 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/editEmail';
const editEmail = async (
props: Props,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
const response = await axios.put(`/channels/${props.id}`, {
name: props.name,
email_configs: [
{
send_resolved: true,
to: props.to,
html: props.html,
headers: props.headers,
},
],
});
return {
statusCode: 200,
error: null,
message: 'Success',
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default editEmail;

View File

@@ -0,0 +1,34 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/createEmail';
const testEmail = async (
props: Props,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
const response = await axios.post('/testChannel', {
name: props.name,
email_configs: [
{
send_resolved: true,
to: props.to,
html: props.html,
headers: props.headers,
},
],
});
return {
statusCode: 200,
error: null,
message: 'Success',
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default testEmail;

View File

@@ -9,7 +9,7 @@ import { ENVIRONMENT } from 'constants/env';
import { LOCALSTORAGE } from 'constants/localStorage'; import { LOCALSTORAGE } from 'constants/localStorage';
import store from 'store'; import store from 'store';
import apiV1, { apiAlertManager, apiV2, apiV3 } from './apiV1'; import apiV1, { apiAlertManager, apiV2, apiV3, apiV4 } from './apiV1';
import { Logout } from './utils'; import { Logout } from './utils';
const interceptorsResponse = ( const interceptorsResponse = (
@@ -114,6 +114,7 @@ ApiV2Instance.interceptors.request.use(interceptorsRequestResponse);
export const ApiV3Instance = axios.create({ export const ApiV3Instance = axios.create({
baseURL: `${ENVIRONMENT.baseURL}${apiV3}`, baseURL: `${ENVIRONMENT.baseURL}${apiV3}`,
}); });
ApiV3Instance.interceptors.response.use( ApiV3Instance.interceptors.response.use(
interceptorsResponse, interceptorsResponse,
interceptorRejected, interceptorRejected,
@@ -121,6 +122,18 @@ ApiV3Instance.interceptors.response.use(
ApiV3Instance.interceptors.request.use(interceptorsRequestResponse); ApiV3Instance.interceptors.request.use(interceptorsRequestResponse);
// //
// axios V4
export const ApiV4Instance = axios.create({
baseURL: `${ENVIRONMENT.baseURL}${apiV4}`,
});
ApiV4Instance.interceptors.response.use(
interceptorsResponse,
interceptorRejected,
);
ApiV4Instance.interceptors.request.use(interceptorsRequestResponse);
//
AxiosAlertManagerInstance.interceptors.response.use( AxiosAlertManagerInstance.interceptors.response.use(
interceptorsResponse, interceptorsResponse,
interceptorRejected, interceptorRejected,

View File

@@ -4,5 +4,6 @@ import { MetricMetaProps } from 'types/api/metrics/getApDex';
export const getMetricMeta = ( export const getMetricMeta = (
metricName: string, metricName: string,
servicename: string,
): Promise<AxiosResponse<MetricMetaProps>> => ): Promise<AxiosResponse<MetricMetaProps>> =>
axios.get(`/metric_meta?metricName=${metricName}`); axios.get(`/metric_meta?metricName=${metricName}&serviceName=${servicename}`);

View File

@@ -1,6 +1,7 @@
import { ApiV3Instance as axios } from 'api'; import { ApiV3Instance, ApiV4Instance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { ErrorResponse, SuccessResponse } from 'types/api'; import { ErrorResponse, SuccessResponse } from 'types/api';
import { import {
MetricRangePayloadV3, MetricRangePayloadV3,
@@ -9,10 +10,23 @@ import {
export const getMetricsQueryRange = async ( export const getMetricsQueryRange = async (
props: QueryRangePayload, props: QueryRangePayload,
version: string,
signal: AbortSignal, signal: AbortSignal,
): Promise<SuccessResponse<MetricRangePayloadV3> | ErrorResponse> => { ): Promise<SuccessResponse<MetricRangePayloadV3> | ErrorResponse> => {
try { try {
const response = await axios.post('/query_range', props, { signal }); if (version && version === ENTITY_VERSION_V4) {
const response = await ApiV4Instance.post('/query_range', props, { signal });
return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data,
params: props,
};
}
const response = await ApiV3Instance.post('/query_range', props, { signal });
return { return {
statusCode: 200, statusCode: 200,

View File

@@ -66,7 +66,11 @@ export const Logout = (): void => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
window.Intercom('shutdown'); if (window && window.Intercom) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
window.Intercom('shutdown');
}
history.push(ROUTES.LOGIN); history.push(ROUTES.LOGIN);
}; };

View File

@@ -0,0 +1,41 @@
import { CSSProperties } from 'react';
function BarIcon({
fillColor,
}: {
fillColor: CSSProperties['color'];
}): JSX.Element {
return (
<svg
width="30"
height="30"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M8 2H6C4.89543 2 4 2.89543 4 4V16C4 17.1046 4.89543 18 6 18H8C9.10457 18 10 17.1046 10 16V4C10 2.89543 9.10457 2 8 2Z"
stroke={fillColor}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M18 9H16C14.8954 9 14 9.89543 14 11V16C14 17.1046 14.8954 18 16 18H18C19.1046 18 20 17.1046 20 16V11C20 9.89543 19.1046 9 18 9Z"
stroke={fillColor}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M22 22H2"
stroke={fillColor}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
export default BarIcon;

View File

@@ -0,0 +1,30 @@
import { CSSProperties } from 'react';
function ListIcon({
fillColor,
}: {
fillColor: CSSProperties['color'];
}): JSX.Element {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="30"
height="30"
viewBox="0 0 24 24"
fill="none"
stroke={fillColor}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<line x1="8" x2="21" y1="6" y2="6" />
<line x1="8" x2="21" y1="12" y2="12" />
<line x1="8" x2="21" y1="18" y2="18" />
<line x1="3" x2="3.01" y1="6" y2="6" />
<line x1="3" x2="3.01" y1="12" y2="12" />
<line x1="3" x2="3.01" y1="18" y2="18" />
</svg>
);
}
export default ListIcon;

View File

@@ -1,18 +1,48 @@
function Table(): JSX.Element { import { CSSProperties } from 'react';
function TableIcon({
fillColor,
}: {
fillColor: CSSProperties['color'];
}): JSX.Element {
return ( return (
<svg <svg
width="48" width="24"
height="48" height="24"
viewBox="0 0 48 48" viewBox="0 0 24 24"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<path <path
d="M41.0667 0H6.39993C2.87982 0 0 2.87982 0 6.39993V41.6001C0 45.1202 2.87982 48 6.39993 48H41.0667C44.5868 48 47.4667 45.1202 47.4667 41.6001V6.39993C47.4667 2.87982 44.5868 0 41.0667 0ZM44.2669 6.39993V9.60013H32.0002V3.2002H41.0668C42.8268 3.2002 44.267 4.63992 44.267 6.40003L44.2669 6.39993ZM17.6002 9.60013V3.2002H29.8669V9.60013H17.6002ZM29.8669 11.7333V44.8001H17.6002L17.6005 11.7333H29.8669ZM6.40012 3.20011H15.4667V9.60004H3.20001V6.39984C3.20001 4.63983 4.64011 3.20001 6.40022 3.20001L6.40012 3.20011ZM3.19992 41.6003V11.7335H15.4666V44.8003H6.40003C4.64002 44.8003 3.19982 43.3606 3.19982 41.6005L3.19992 41.6003ZM41.0667 44.8001H32.0001V11.7333H44.2668V41.6001C44.2668 43.3601 42.8267 44.7999 41.0666 44.7999L41.0667 44.8001ZM5.33326 18.6666C5.33326 18.08 5.81317 17.6001 6.39983 17.6001H12.2667C12.8534 17.6001 13.3333 18.08 13.3333 18.6666C13.3333 19.2533 12.8534 19.7332 12.2667 19.7332H6.39983C5.81315 19.7332 5.33326 19.2533 5.33326 18.6666ZM13.3333 25.0666C13.3333 25.6533 12.8534 26.1332 12.2667 26.1332H6.39983C5.81315 26.1332 5.33326 25.6532 5.33326 25.0666C5.33326 24.4799 5.81317 24 6.39983 24H12.2667C12.8534 24 13.3333 24.4799 13.3333 25.0666ZM13.3333 31.4665C13.3333 32.0532 12.8534 32.5331 12.2667 32.5331H6.39983C5.81315 32.5331 5.33326 32.0532 5.33326 31.4665C5.33326 30.8798 5.81317 30.3999 6.39983 30.3999H12.2667C12.8534 30.3999 13.3333 30.8798 13.3333 31.4665ZM13.3333 37.8668C13.3333 38.4535 12.8534 38.9334 12.2667 38.9334H6.39983C5.81315 38.9334 5.33326 38.4535 5.33326 37.8668C5.33326 37.2801 5.81317 36.8002 6.39983 36.8002H12.2667C12.8534 36.7999 13.3333 37.2802 13.3333 37.8668ZM19.7332 18.6667C19.7332 18.0801 20.2131 17.6002 20.7998 17.6002H26.6667C27.2534 17.6002 27.7333 18.0801 27.7333 18.6667C27.7333 19.2534 27.2533 19.7333 26.6667 19.7333H20.7998C20.2131 19.7333 19.7332 19.2534 19.7332 18.6667ZM19.7332 25.0667C19.7332 24.48 20.2131 24.0001 20.7998 24.0001H26.6667C27.2534 24.0001 27.7333 24.48 27.7333 25.0667C27.7333 25.6534 27.2533 26.1332 26.6667 26.1332H20.7998C20.2131 26.1332 19.7332 25.6533 19.7332 25.0667ZM19.7332 31.4666C19.7332 30.8799 20.2131 30.4 20.7998 30.4H26.6667C27.2534 30.4 27.7333 30.8799 27.7333 31.4666C27.7333 32.0533 27.2533 32.5332 26.6667 32.5332H20.7998C20.2131 32.5336 19.7332 32.0533 19.7332 31.4666ZM27.7333 37.8669C27.7333 38.4536 27.2533 38.9335 26.6667 38.9335H20.7998C20.2131 38.9335 19.7332 38.4536 19.7332 37.8669C19.7332 37.2802 20.2131 36.8003 20.7998 36.8003H26.6667C27.2534 36.8 27.7333 37.2803 27.7333 37.8669ZM42.1333 18.6668C42.1333 19.2535 41.6534 19.7334 41.0667 19.7334H35.1999C34.6132 19.7334 34.1333 19.2535 34.1333 18.6668C34.1333 18.0802 34.6132 17.6003 35.1999 17.6003H41.0667C41.6534 17.6003 42.1333 18.0802 42.1333 18.6668ZM42.1333 25.0668C42.1333 25.6535 41.6534 26.1333 41.0667 26.1333H35.1999C34.6132 26.1333 34.1333 25.6534 34.1333 25.0668C34.1333 24.4801 34.6132 24.0002 35.1999 24.0002H41.0667C41.6534 24.0002 42.1333 24.4801 42.1333 25.0668ZM42.1333 31.4667C42.1333 32.0534 41.6534 32.5333 41.0667 32.5333H35.1999C34.6132 32.5333 34.1333 32.0534 34.1333 31.4667C34.1333 30.88 34.6132 30.4001 35.1999 30.4001H41.0667C41.6534 30.4001 42.1333 30.88 42.1333 31.4667ZM42.1333 37.867C42.1333 38.4537 41.6534 38.9336 41.0667 38.9336H35.1999C34.6132 38.9336 34.1333 38.4537 34.1333 37.867C34.1333 37.2803 34.6132 36.8004 35.1999 36.8004H41.0667C41.6534 36.8001 42.1333 37.2803 42.1333 37.867Z" d="M12 3V21"
fill="#1668DC" stroke={fillColor}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M19 3H5C3.89543 3 3 3.89543 3 5V19C3 20.1046 3.89543 21 5 21H19C20.1046 21 21 20.1046 21 19V5C21 3.89543 20.1046 3 19 3Z"
stroke={fillColor}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M3 9H21"
stroke={fillColor}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M3 15H21"
stroke={fillColor}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/> />
</svg> </svg>
); );
} }
export default Table; export default TableIcon;

File diff suppressed because one or more lines are too long

View File

@@ -1,19 +1,29 @@
function Value(): JSX.Element { import { CSSProperties } from 'react';
function Value({
fillColor,
}: {
fillColor: CSSProperties['color'];
}): JSX.Element {
return ( return (
<svg <svg
width="68" width="30"
height="48" height="30"
viewBox="0 0 68 48" viewBox="0 0 24 24"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<path <path
d="M0 5.914V42.086C0 43.6542 0.62289 45.1585 1.73183 46.2675C2.84078 47.3771 4.34511 48 5.91329 48H61.5019C63.0701 48 64.5744 47.3771 65.6834 46.2675C66.7923 45.1585 67.4152 43.6542 67.4152 42.086V5.914C67.4152 4.34578 66.7923 2.84152 65.6834 1.73253C64.5744 0.623576 63.0701 0 61.5019 0H5.91329C4.34508 0 2.84082 0.623576 1.73183 1.73253C0.622872 2.84149 0 4.34581 0 5.914ZM63.4735 5.914V42.086C63.4735 42.6092 63.2659 43.1104 62.896 43.4803C62.5261 43.8495 62.0249 44.0571 61.5024 44.0571H5.91382C4.82549 44.0571 3.94277 43.175 3.94277 42.086V5.91403C3.94277 4.8257 4.82553 3.94298 5.91382 3.94298H61.5024C62.0249 3.94298 62.5261 4.15061 62.896 4.52048C63.2659 4.88968 63.4735 5.39148 63.4735 5.914Z" d="M9 3H5C4.46957 3 3.96086 3.21071 3.58579 3.58579C3.21071 3.96086 3 4.46957 3 5V9M9 3H19C19.5304 3 20.0391 3.21071 20.4142 3.58579C20.7893 3.96086 21 4.46957 21 5V9M9 21H19C19.5304 21 20.0391 20.7893 20.4142 20.4142C20.7893 20.0391 21 19.5304 21 19V9M9 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V9"
fill="#1554AD" stroke="white"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
fill={fillColor}
/> />
<path <path
d="M13.7695 17.668C10.1016 17.668 7.48828 20.1758 7.48828 23.6094V23.6328C7.48828 26.8438 9.76172 29.2109 13.0078 29.2109C15.3281 29.2109 16.8047 28.0273 17.4258 26.6914H17.6602C17.6602 26.8203 17.6484 26.9492 17.6484 27.0781C17.5195 30.3125 16.3828 32.9375 13.6992 32.9375C12.2109 32.9375 11.168 32.1641 10.7227 30.9805L10.6875 30.8633H7.71094L7.73438 30.9922C8.27344 33.582 10.5938 35.4219 13.6992 35.4219C17.9531 35.4219 20.5195 32.0469 20.5195 26.3516V26.3281C20.5195 20.2344 17.3789 17.668 13.7695 17.668ZM13.7578 26.8906C11.8359 26.8906 10.4414 25.4844 10.4414 23.5273V23.5039C10.4414 21.6172 11.9297 20.1289 13.793 20.1289C15.668 20.1289 17.1328 21.6406 17.1328 23.5742V23.5977C17.1328 25.5078 15.668 26.8906 13.7578 26.8906ZM24.832 35.2344C25.9102 35.2344 26.6953 34.4258 26.6953 33.3828C26.6953 32.3398 25.9102 31.5312 24.832 31.5312C23.7656 31.5312 22.9688 32.3398 22.9688 33.3828C22.9688 34.4258 23.7656 35.2344 24.832 35.2344ZM37.8633 35H40.7578V31.7539H43.0312V29.2578H40.7578V18.0898H36.4805C34.1836 21.582 31.7812 25.4727 29.5898 29.2812V31.7539H37.8633V35ZM32.4023 29.3281V29.1523C34.043 26.2812 36 23.1523 37.7344 20.5039H37.9102V29.3281H32.4023ZM52.6406 35.4219C56.3086 35.4219 58.9219 32.9141 58.9219 29.4805V29.457C58.9219 26.2461 56.6484 23.8789 53.4023 23.8789C51.082 23.8789 49.6055 25.0625 48.9844 26.3984H48.75C48.75 26.2695 48.7617 26.1406 48.7617 26.0117C48.8906 22.7773 50.0273 20.1523 52.7109 20.1523C54.1992 20.1523 55.2422 20.9258 55.6875 22.1094L55.7344 22.2266H58.6992L58.6758 22.0977C58.1367 19.5078 55.8164 17.668 52.7109 17.668C48.457 17.668 45.8906 21.043 45.8906 26.7383V26.7617C45.8906 32.8555 49.0312 35.4219 52.6406 35.4219ZM49.2773 29.5156V29.4922C49.2773 27.582 50.7422 26.1992 52.6523 26.1992C54.5742 26.1992 55.9688 27.6055 55.9688 29.5625V29.5859C55.9688 31.4727 54.4922 32.9609 52.6172 32.9609C50.7422 32.9609 49.2773 31.4492 49.2773 29.5156Z" d="M9.76562 15.6221C9.19922 15.6221 8.78906 15.3047 8.78906 14.6406V14.3818H6.58691C5.83984 14.3818 5.32227 13.9082 5.32227 13.2246C5.32227 12.8486 5.44922 12.4531 5.72266 11.9648C6.18164 11.1396 6.61621 10.4219 7.1582 9.57227C7.74414 8.64941 8.22266 8.33203 9.02832 8.33203C10.0586 8.33203 10.7422 8.90332 10.7422 9.76758V12.7949H10.9033C11.4453 12.7949 11.7041 13.1318 11.7041 13.5908C11.7041 14.0498 11.4404 14.3818 10.8984 14.3818H10.7422V14.6406C10.7422 15.3047 10.3271 15.6221 9.76562 15.6221ZM8.84766 12.8779V9.83594H8.80859C8.10059 10.8711 7.58789 11.6914 7.0166 12.8193V12.8779H8.84766ZM13.2959 15.5C12.6221 15.5 12.3291 15.124 12.3291 14.6064C12.3291 14.2256 12.5049 13.9326 12.8955 13.6055L14.834 11.9453C15.625 11.2666 15.8496 10.959 15.8496 10.5391C15.8496 10.0947 15.5078 9.78711 15.0049 9.78711C14.6338 9.78711 14.3799 9.95801 14.1162 10.3389C13.8428 10.7393 13.5938 10.8857 13.1982 10.8857C12.6709 10.8857 12.3486 10.5781 12.3486 10.0801C12.3486 9.91895 12.3779 9.76758 12.4414 9.62109C12.8125 8.78125 13.8037 8.25879 15.0342 8.25879C16.748 8.25879 17.8418 9.12305 17.8418 10.4023C17.8418 11.3496 17.3535 11.8428 16.2598 12.79L14.9756 13.8984V13.9375H17.2119C17.7295 13.9375 18.0225 14.2451 18.0225 14.7188C18.0225 15.1826 17.7295 15.5 17.2119 15.5H13.2959Z"
fill="#1668DC" fill={fillColor}
/> />
</svg> </svg>
); );

View File

@@ -0,0 +1,121 @@
.custom-time-picker {
display: flex;
flex-direction: column;
}
.time-options-container {
.time-options-item {
margin: 2px 0;
padding: 8px;
border-radius: 2px;
&.active {
background-color: rgba($color: #000000, $alpha: 0.2);
&:hover {
cursor: pointer;
background-color: rgba($color: #000000, $alpha: 0.3);
}
}
&:hover {
cursor: pointer;
background-color: rgba($color: #000000, $alpha: 0.3);
}
}
}
.time-selection-dropdown-content {
min-width: 172px;
width: 100%;
}
.timeSelection-input {
display: flex;
gap: 8px;
height: 33px;
align-items: center;
padding: 4px 8px;
padding-left: 0px !important;
&.custom-time {
input:not(:focus) {
min-width: 240px;
}
}
input::placeholder {
color: white;
}
input:focus::placeholder {
color: rgba($color: #ffffff, $alpha: 0.4);
}
}
.valid-format-error {
margin-top: 4px;
color: var(--bg-cherry-400) !important;
font-size: 13px !important;
font-weight: 400 !important;
}
.info-text {
display: flex;
align-items: center;
justify-content: center;
padding: 4px;
cursor: default;
color: var(--bg-vanilla-400, #c0c1c3) !important;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: normal;
letter-spacing: 0.14px;
}
.info-text:hover {
&.ant-btn-text {
background-color: unset !important;
}
}
.lightMode {
.time-options-container {
.time-options-item {
&.active {
background-color: rgba($color: #ffffff, $alpha: 0.2);
&:hover {
cursor: pointer;
background-color: rgba($color: #ffffff, $alpha: 0.3);
}
}
&:hover {
cursor: pointer;
background-color: rgba($color: #ffffff, $alpha: 0.3);
}
}
}
.timeSelection-input {
display: flex;
gap: 8px;
align-items: center;
padding: 4px 8px;
padding-left: 0px !important;
input::placeholder {
color: var(---bg-ink-300);
}
input:focus::placeholder {
color: rgba($color: #000000, $alpha: 0.4);
}
}
.info-text {
color: var(--bg-slate-400) !important;
}
}

View File

@@ -0,0 +1,323 @@
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-static-element-interactions */
import './CustomTimePicker.styles.scss';
import { Input, Popover, Tooltip, Typography } from 'antd';
import cx from 'classnames';
import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal';
import { Options } from 'container/TopNav/DateTimeSelection/config';
import {
FixedDurationSuggestionOptions,
RelativeDurationSuggestionOptions,
} from 'container/TopNav/DateTimeSelectionV2/config';
import dayjs from 'dayjs';
import { defaultTo, noop } from 'lodash-es';
import debounce from 'lodash-es/debounce';
import { CheckCircle, ChevronDown, Clock } from 'lucide-react';
import {
ChangeEvent,
Dispatch,
SetStateAction,
useEffect,
useState,
} from 'react';
import { useLocation } from 'react-router-dom';
import { popupContainer } from 'utils/selectPopupContainer';
import CustomTimePickerPopoverContent from './CustomTimePickerPopoverContent';
const maxAllowedMinTimeInMonths = 6;
interface CustomTimePickerProps {
onSelect: (value: string) => void;
onError: (value: boolean) => void;
selectedValue: string;
selectedTime: string;
onValidCustomDateChange: ([t1, t2]: any[]) => void;
open: boolean;
setOpen: Dispatch<SetStateAction<boolean>>;
items: any[];
newPopover?: boolean;
customDateTimeVisible?: boolean;
setCustomDTPickerVisible?: Dispatch<SetStateAction<boolean>>;
onCustomDateHandler?: (dateTimeRange: DateTimeRangeType) => void;
handleGoLive?: () => void;
}
function CustomTimePicker({
onSelect,
onError,
items,
selectedValue,
selectedTime,
open,
setOpen,
onValidCustomDateChange,
newPopover,
customDateTimeVisible,
setCustomDTPickerVisible,
onCustomDateHandler,
handleGoLive,
}: CustomTimePickerProps): JSX.Element {
const [
selectedTimePlaceholderValue,
setSelectedTimePlaceholderValue,
] = useState('Select / Enter Time Range');
const [inputValue, setInputValue] = useState('');
const [inputStatus, setInputStatus] = useState<'' | 'error' | 'success'>('');
const [inputErrorMessage, setInputErrorMessage] = useState<string | null>(
null,
);
const location = useLocation();
const [isInputFocused, setIsInputFocused] = useState(false);
const getSelectedTimeRangeLabel = (
selectedTime: string,
selectedTimeValue: string,
): string => {
if (selectedTime === 'custom') {
return selectedTimeValue;
}
for (let index = 0; index < Options.length; index++) {
if (Options[index].value === selectedTime) {
return Options[index].label;
}
}
for (
let index = 0;
index < RelativeDurationSuggestionOptions.length;
index++
) {
if (RelativeDurationSuggestionOptions[index].value === selectedTime) {
return RelativeDurationSuggestionOptions[index].label;
}
}
for (let index = 0; index < FixedDurationSuggestionOptions.length; index++) {
if (FixedDurationSuggestionOptions[index].value === selectedTime) {
return FixedDurationSuggestionOptions[index].label;
}
}
return '';
};
useEffect(() => {
const value = getSelectedTimeRangeLabel(selectedTime, selectedValue);
setSelectedTimePlaceholderValue(value);
}, [selectedTime, selectedValue]);
const hide = (): void => {
setOpen(false);
};
const handleOpenChange = (newOpen: boolean): void => {
setOpen(newOpen);
if (!newOpen) {
setCustomDTPickerVisible?.(false);
}
};
const debouncedHandleInputChange = debounce((inputValue): void => {
const isValidFormat = /^(\d+)([mhdw])$/.test(inputValue);
if (isValidFormat) {
setInputStatus('success');
onError(false);
setInputErrorMessage(null);
const match = inputValue.match(/^(\d+)([mhdw])$/);
const value = parseInt(match[1], 10);
const unit = match[2];
const currentTime = dayjs();
const maxAllowedMinTime = currentTime.subtract(
maxAllowedMinTimeInMonths,
'month',
);
let minTime = null;
switch (unit) {
case 'm':
minTime = currentTime.subtract(value, 'minute');
break;
case 'h':
minTime = currentTime.subtract(value, 'hour');
break;
case 'd':
minTime = currentTime.subtract(value, 'day');
break;
case 'w':
minTime = currentTime.subtract(value, 'week');
break;
default:
break;
}
if (minTime && (!minTime.isValid() || minTime < maxAllowedMinTime)) {
setInputStatus('error');
onError(true);
setInputErrorMessage('Please enter time less than 6 months');
} else {
onValidCustomDateChange([minTime, currentTime]);
}
} else {
setInputStatus('error');
onError(true);
setInputErrorMessage(null);
}
}, 300);
const handleInputChange = (event: ChangeEvent<HTMLInputElement>): void => {
const inputValue = event.target.value;
if (inputValue.length > 0) {
setOpen(false);
} else {
setOpen(true);
}
setInputValue(inputValue);
// Call the debounced function with the input value
debouncedHandleInputChange(inputValue);
};
const handleSelect = (label: string, value: string): void => {
onSelect(value);
setSelectedTimePlaceholderValue(label);
setInputStatus('');
onError(false);
setInputErrorMessage(null);
setInputValue('');
if (value !== 'custom') {
hide();
}
};
const content = (
<div className="time-selection-dropdown-content">
<div className="time-options-container">
{items?.map(({ value, label }) => (
<div
onClick={(): void => {
handleSelect(label, value);
}}
key={value}
className={cx(
'time-options-item',
selectedValue === value ? 'active' : '',
)}
>
{label}
</div>
))}
</div>
</div>
);
const handleFocus = (): void => {
setIsInputFocused(true);
};
const handleBlur = (): void => {
setIsInputFocused(false);
};
// this is required as TopNav component wraps the components and we need to clear the state on path change
useEffect(() => {
setInputStatus('');
onError(false);
setInputErrorMessage(null);
setInputValue('');
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [location.pathname]);
return (
<div className="custom-time-picker">
<Popover
className={cx(
'timeSelection-input-container',
selectedTime === 'custom' && inputValue === '' ? 'custom-time' : '',
)}
placement="bottomRight"
getPopupContainer={popupContainer}
rootClassName="date-time-root"
content={
newPopover ? (
<CustomTimePickerPopoverContent
setIsOpen={setOpen}
customDateTimeVisible={defaultTo(customDateTimeVisible, false)}
setCustomDTPickerVisible={defaultTo(setCustomDTPickerVisible, noop)}
onCustomDateHandler={defaultTo(onCustomDateHandler, noop)}
onSelectHandler={handleSelect}
handleGoLive={defaultTo(handleGoLive, noop)}
options={items}
selectedTime={selectedTime}
/>
) : (
content
)
}
arrow={false}
trigger="hover"
open={open}
onOpenChange={handleOpenChange}
style={{
padding: 0,
}}
>
<Input
className="timeSelection-input"
type="text"
status={inputValue && inputStatus === 'error' ? 'error' : ''}
placeholder={
isInputFocused
? 'Time Format (1m or 2h or 3d or 4w)'
: selectedTimePlaceholderValue
}
value={inputValue}
onFocus={handleFocus}
onBlur={handleBlur}
onChange={handleInputChange}
prefix={
inputValue && inputStatus === 'success' ? (
<CheckCircle size={14} color="#51E7A8" />
) : (
<Tooltip title="Enter time in format (e.g., 1m, 2h, 3d, 4w)">
<Clock size={14} />
</Tooltip>
)
}
suffix={
<ChevronDown
size={14}
onClick={(): void => {
setOpen(!open);
}}
/>
}
/>
</Popover>
{inputStatus === 'error' && inputErrorMessage && (
<Typography.Title level={5} className="valid-format-error">
{inputErrorMessage}
</Typography.Title>
)}
</div>
);
}
export default CustomTimePicker;
CustomTimePicker.defaultProps = {
newPopover: false,
customDateTimeVisible: false,
setCustomDTPickerVisible: noop,
onCustomDateHandler: noop,
handleGoLive: noop,
};

View File

@@ -0,0 +1,118 @@
import './CustomTimePicker.styles.scss';
import { Button } from 'antd';
import cx from 'classnames';
import ROUTES from 'constants/routes';
import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal';
import {
LexicalContext,
Option,
RelativeDurationSuggestionOptions,
} from 'container/TopNav/DateTimeSelectionV2/config';
import { Dispatch, SetStateAction, useMemo } from 'react';
import { useLocation } from 'react-router-dom';
import RangePickerModal from './RangePickerModal';
interface CustomTimePickerPopoverContentProps {
options: any[];
setIsOpen: Dispatch<SetStateAction<boolean>>;
customDateTimeVisible: boolean;
setCustomDTPickerVisible: Dispatch<SetStateAction<boolean>>;
onCustomDateHandler: (
dateTimeRange: DateTimeRangeType,
lexicalContext?: LexicalContext,
) => void;
onSelectHandler: (label: string, value: string) => void;
handleGoLive: () => void;
selectedTime: string;
}
function CustomTimePickerPopoverContent({
options,
setIsOpen,
customDateTimeVisible,
setCustomDTPickerVisible,
onCustomDateHandler,
onSelectHandler,
handleGoLive,
selectedTime,
}: CustomTimePickerPopoverContentProps): JSX.Element {
const { pathname } = useLocation();
const isLogsExplorerPage = useMemo(() => pathname === ROUTES.LOGS_EXPLORER, [
pathname,
]);
function getTimeChips(options: Option[]): JSX.Element {
return (
<div className="relative-date-time-section">
{options.map((option) => (
<Button
type="text"
className="time-btns"
key={option.label + option.value}
onClick={(): void => {
onSelectHandler(option.label, option.value);
}}
>
{option.label}
</Button>
))}
</div>
);
}
return (
<div className="date-time-popover">
<div className="date-time-options">
{isLogsExplorerPage && (
<Button className="data-time-live" type="text" onClick={handleGoLive}>
Live
</Button>
)}
{options.map((option) => (
<Button
type="text"
key={option.label + option.value}
onClick={(): void => {
onSelectHandler(option.label, option.value);
}}
className={cx(
'date-time-options-btn',
customDateTimeVisible
? option.value === 'custom' && 'active'
: selectedTime === option.value && 'active',
)}
>
{option.label}
</Button>
))}
</div>
<div
className={cx(
'relative-date-time',
selectedTime === 'custom' || customDateTimeVisible
? 'date-picker'
: 'relative-times',
)}
>
{selectedTime === 'custom' || customDateTimeVisible ? (
<RangePickerModal
setCustomDTPickerVisible={setCustomDTPickerVisible}
setIsOpen={setIsOpen}
onCustomDateHandler={onCustomDateHandler}
selectedTime={selectedTime}
/>
) : (
<div className="relative-times-container">
<div className="time-heading">RELATIVE TIMES</div>
<div>{getTimeChips(RelativeDurationSuggestionOptions)}</div>
</div>
)}
</div>
</div>
);
}
export default CustomTimePickerPopoverContent;

View File

@@ -0,0 +1,4 @@
.custom-date-picker {
display: flex;
flex-direction: column;
}

View File

@@ -0,0 +1,68 @@
import './RangePickerModal.styles.scss';
import { DatePicker } from 'antd';
import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal';
import { LexicalContext } from 'container/TopNav/DateTimeSelectionV2/config';
import dayjs, { Dayjs } from 'dayjs';
import { Dispatch, SetStateAction } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { GlobalReducer } from 'types/reducer/globalTime';
interface RangePickerModalProps {
setCustomDTPickerVisible: Dispatch<SetStateAction<boolean>>;
setIsOpen: Dispatch<SetStateAction<boolean>>;
onCustomDateHandler: (
dateTimeRange: DateTimeRangeType,
lexicalContext?: LexicalContext | undefined,
) => void;
selectedTime: string;
}
function RangePickerModal(props: RangePickerModalProps): JSX.Element {
const {
setCustomDTPickerVisible,
setIsOpen,
onCustomDateHandler,
selectedTime,
} = props;
const { RangePicker } = DatePicker;
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
const disabledDate = (current: Dayjs): boolean => {
const currentDay = dayjs(current);
return currentDay.isAfter(dayjs());
};
const onPopoverClose = (visible: boolean): void => {
if (!visible) {
setCustomDTPickerVisible(false);
}
setIsOpen(visible);
};
const onModalOkHandler = (date_time: any): void => {
if (date_time?.[1]) {
onPopoverClose(false);
}
onCustomDateHandler(date_time, LexicalContext.CUSTOM_DATE_PICKER);
};
return (
<div className="custom-date-picker">
<RangePicker
disabledDate={disabledDate}
allowClear
showTime
onOk={onModalOkHandler}
// eslint-disable-next-line react/jsx-props-no-spreading
{...(selectedTime === 'custom' && {
defaultValue: [dayjs(minTime / 1000000), dayjs(maxTime / 1000000)],
})}
/>
</div>
);
}
export default RangePickerModal;

View File

@@ -6,7 +6,6 @@ import {
} from '@ant-design/icons'; } from '@ant-design/icons';
import { import {
Button, Button,
Card,
Col, Col,
Dropdown, Dropdown,
MenuProps, MenuProps,
@@ -152,95 +151,100 @@ function ExplorerCard({
const saveButtonType = isQueryUpdated ? 'default' : 'primary'; const saveButtonType = isQueryUpdated ? 'default' : 'primary';
const saveButtonIcon = isQueryUpdated ? null : <SaveOutlined />; const saveButtonIcon = isQueryUpdated ? null : <SaveOutlined />;
const showSaveView = false;
return ( return (
<> <>
<ExplorerCardHeadContainer size="small"> {showSaveView && (
<Row align="middle"> <ExplorerCardHeadContainer size="small">
<Col span={6}> <Row align="middle">
<Space> <Col span={6}>
<Typography>Query Builder</Typography> <Space>
<TextToolTip <Typography>Query Builder</Typography>
url={ExploreHeaderToolTip.url} <TextToolTip
text={ExploreHeaderToolTip.text} url={ExploreHeaderToolTip.url}
useFilledIcon={false} text={ExploreHeaderToolTip.text}
/> useFilledIcon={false}
</Space> />
</Col> </Space>
<OffSetCol span={18}> </Col>
<Space size="large"> <OffSetCol span={18}>
{viewsData?.data.data && viewsData?.data.data.length && ( <Space size="large">
<Space> {viewsData?.data.data && viewsData?.data.data.length && (
<Select <Space>
getPopupContainer={popupContainer} <Select
loading={isLoading || isRefetching} getPopupContainer={popupContainer}
showSearch loading={isLoading || isRefetching}
placeholder="Select a view" showSearch
dropdownStyle={DropDownOverlay} placeholder="Select a view"
dropdownMatchSelectWidth={false} dropdownStyle={DropDownOverlay}
optionLabelProp="value" dropdownMatchSelectWidth={false}
value={viewName || undefined} optionLabelProp="value"
value={viewName || undefined}
>
{viewsData?.data.data.map((view) => (
<Select.Option key={view.uuid} value={view.name}>
<MenuItemGenerator
viewName={view.name}
viewKey={viewKey}
createdBy={view.createdBy}
uuid={view.uuid}
refetchAllView={refetchAllView}
viewData={viewsData.data.data}
sourcePage={sourcepage}
/>
</Select.Option>
))}
</Select>
</Space>
)}
{isQueryUpdated && (
<Button
type="primary"
icon={<SaveOutlined />}
onClick={onUpdateQueryHandler}
> >
{viewsData?.data.data.map((view) => ( Save changes
<Select.Option key={view.uuid} value={view.name}> </Button>
<MenuItemGenerator )}
viewName={view.name} <Popover
viewKey={viewKey} getPopupContainer={popupContainer}
createdBy={view.createdBy} placement="bottomLeft"
uuid={view.uuid} trigger="click"
refetchAllView={refetchAllView} content={
viewData={viewsData.data.data} <SaveViewWithName
sourcePage={sourcepage} sourcePage={sourcepage}
/> handlePopOverClose={handleOpenChange}
</Select.Option> refetchAllView={refetchAllView}
))} />
</Select> }
</Space> showArrow={false}
)} open={isOpen}
{isQueryUpdated && ( onOpenChange={handleOpenChange}
<Button
type="primary"
icon={<SaveOutlined />}
onClick={onUpdateQueryHandler}
> >
Save changes <Button
</Button> type={saveButtonType}
)} icon={saveButtonIcon}
<Popover data-testid="traces-save-view-action"
getPopupContainer={popupContainer} >
placement="bottomLeft" {isQueryUpdated
trigger="click" ? SaveButtonText.SAVE_AS_NEW_VIEW
content={ : SaveButtonText.SAVE_VIEW}
<SaveViewWithName </Button>
sourcePage={sourcepage} </Popover>
handlePopOverClose={handleOpenChange} <ShareAltOutlined onClick={onCopyUrlHandler} />
refetchAllView={refetchAllView} {viewKey && (
/> <Dropdown trigger={['click']} menu={moreOptionMenu}>
} <MoreOutlined />
showArrow={false} </Dropdown>
open={isOpen} )}
onOpenChange={handleOpenChange} </Space>
> </OffSetCol>
<Button </Row>
type={saveButtonType} </ExplorerCardHeadContainer>
icon={saveButtonIcon} )}
data-testid="traces-save-view-action"
> <div>{children}</div>
{isQueryUpdated
? SaveButtonText.SAVE_AS_NEW_VIEW
: SaveButtonText.SAVE_VIEW}
</Button>
</Popover>
<ShareAltOutlined onClick={onCopyUrlHandler} />
{viewKey && (
<Dropdown trigger={['click']} menu={moreOptionMenu}>
<MoreOutlined />
</Dropdown>
)}
</Space>
</OffSetCol>
</Row>
</ExplorerCardHeadContainer>
<Card>{children}</Card>
</> </>
); );
} }

View File

@@ -3,6 +3,7 @@ import styled, { CSSProperties } from 'styled-components';
export const ExplorerCardHeadContainer = styled(Card)` export const ExplorerCardHeadContainer = styled(Card)`
margin: 1rem 0; margin: 1rem 0;
padding: 0;
`; `;
export const OffSetCol = styled(Col)` export const OffSetCol = styled(Col)`

View File

@@ -1,4 +1,4 @@
import { fireEvent, render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import MockQueryClientProvider from 'providers/test/MockQueryClientProvider'; import MockQueryClientProvider from 'providers/test/MockQueryClientProvider';
import { DataSource } from 'types/common/queryBuilder'; import { DataSource } from 'types/common/queryBuilder';
@@ -46,7 +46,7 @@ describe('ExplorerCard', () => {
<ExplorerCard sourcepage={DataSource.TRACES}>child</ExplorerCard> <ExplorerCard sourcepage={DataSource.TRACES}>child</ExplorerCard>
</MockQueryClientProvider>, </MockQueryClientProvider>,
); );
expect(screen.getByText('Query Builder')).toBeInTheDocument(); expect(screen.queryByText('Query Builder')).not.toBeInTheDocument();
}); });
it('renders a save view button', () => { it('renders a save view button', () => {
@@ -55,19 +55,6 @@ describe('ExplorerCard', () => {
<ExplorerCard sourcepage={DataSource.TRACES}>child</ExplorerCard> <ExplorerCard sourcepage={DataSource.TRACES}>child</ExplorerCard>
</MockQueryClientProvider>, </MockQueryClientProvider>,
); );
expect(screen.getByText('Save view')).toBeInTheDocument(); expect(screen.queryByText('Save view')).not.toBeInTheDocument();
});
it('should see all the view listed in dropdown', async () => {
const screen = render(
<ExplorerCard sourcepage={DataSource.TRACES}>Mock Children</ExplorerCard>,
);
const selectPlaceholder = screen.getByText('Select a view');
fireEvent.mouseDown(selectPlaceholder);
const viewNameText = await screen.getAllByText('View 1');
viewNameText.forEach((element) => {
expect(element).toBeInTheDocument();
});
}); });
}); });

View File

@@ -14,7 +14,7 @@ import {
SaveViewHandlerProps, SaveViewHandlerProps,
} from './types'; } from './types';
const showErrorNotification = ( export const showErrorNotification = (
notifications: NotificationInstance, notifications: NotificationInstance,
err: Error, err: Error,
): void => { ): void => {
@@ -90,6 +90,14 @@ export const isQueryUpdatedInView = ({
// Omitting id from aggregateAttribute and groupBy // Omitting id from aggregateAttribute and groupBy
const updatedCurrentQuery = omitIdFromQuery(stagedQuery); const updatedCurrentQuery = omitIdFromQuery(stagedQuery);
if (
updatedCurrentQuery?.builder === undefined ||
updatedCurrentQuery.clickhouse_sql === undefined ||
updatedCurrentQuery.promql === undefined
) {
return false;
}
return ( return (
panelType !== currentPanelType || panelType !== currentPanelType ||
!isEqual(query.builder, updatedCurrentQuery?.builder) || !isEqual(query.builder, updatedCurrentQuery?.builder) ||

View File

@@ -3,8 +3,12 @@ import { AddToQueryHOCProps } from 'components/Logs/AddToQueryHOC';
import { ActionItemProps } from 'container/LogDetailedView/ActionItem'; import { ActionItemProps } from 'container/LogDetailedView/ActionItem';
import { ILog } from 'types/api/logs/log'; import { ILog } from 'types/api/logs/log';
import { VIEWS } from './constants';
export type LogDetailProps = { export type LogDetailProps = {
log: ILog | null; log: ILog | null;
selectedTab: VIEWS;
isListViewPanel?: boolean;
} & Pick<AddToQueryHOCProps, 'onAddToQuery'> & } & Pick<AddToQueryHOCProps, 'onAddToQuery'> &
Pick<ActionItemProps, 'onClickActionItem'> & Partial<Pick<ActionItemProps, 'onClickActionItem'>> &
Pick<DrawerProps, 'onClose'>; Pick<DrawerProps, 'onClose'>;

View File

@@ -0,0 +1,232 @@
.log-detail-drawer {
border-left: 1px solid var(--bg-slate-500);
background: var(--bg-ink-400);
box-shadow: -4px 10px 16px 2px rgba(0, 0, 0, 0.2);
.ant-drawer-header {
padding: 8px 16px;
border-bottom: none;
align-items: stretch;
border-bottom: 1px solid var(--bg-slate-500);
background: var(--bg-ink-400);
}
.ant-drawer-close {
margin-inline-end: 0px;
}
.ant-drawer-body {
display: flex;
flex-direction: column;
padding: 16px;
}
.title {
color: var(--text-vanilla-400);
font-family: Inter;
font-size: var(--font-size-sm);
font-style: normal;
font-weight: var(--font-weight-normal);
line-height: 20px; /* 142.857% */
letter-spacing: -0.07px;
}
.radio-button {
display: flex;
align-items: center;
justify-content: center;
padding-top: var(--padding-1);
border: 1px solid var(--bg-slate-400);
background: var(--bg-ink-300);
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
}
.log-detail-drawer__log {
width: 100%;
display: flex;
align-items: center;
gap: 4px;
position: relative;
.log-body {
font-family: 'SF Mono';
font-family: 'Space Mono', monospace;
font-size: var(--font-size-sm);
font-weight: var(--font-weight-normal);
line-height: 18px;
letter-spacing: -0.07px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
color: var(--text-vanilla-400);
opacity: 0.6;
}
.log-type-indicator {
height: 24px;
border: 2px solid var(--bg-slate-400);
border-radius: 5px;
margin-left: 0;
&.INFO {
border-color: #1d212d;
}
&.WARNING {
border-color: #ffcd56;
}
&.ERROR {
border-color: #e5484d;
}
}
.log-overflow-shadow {
background: linear-gradient(270deg, #121317 10.4%, rgba(18, 19, 23, 0) 100%);
width: 196px;
position: absolute;
right: 0;
}
}
.tabs-and-search {
display: flex;
justify-content: space-between;
align-items: center;
margin: 16px 0;
.action-btn {
border-radius: 2px;
border: 1px solid var(--bg-slate-400);
background: var(--bg-ink-300);
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
justify-content: center;
}
.json-action-btn {
display: flex;
gap: 8px;
}
}
.views-tabs {
color: var(--text-vanilla-400);
.view-title {
display: flex;
gap: var(--margin-2);
align-items: center;
justify-content: center;
font-size: var(--font-size-xs);
font-style: normal;
font-weight: var(--font-weight-normal);
}
.tab {
border: 1px solid var(--bg-slate-400);
width: 114px;
}
.tab::before {
background: var(--bg-slate-400);
}
.selected_view {
background: var(--bg-slate-300);
color: var(--text-vanilla-100);
border: 1px solid var(--bg-slate-400);
}
.selected_view::before {
background: var(--bg-slate-400);
}
}
.search-input {
margin-top: var(--margin-2);
border: 1px solid var(--bg-slate-400);
height: 46px;
padding: var(--padding-1) var(--padding-2);
box-shadow: none;
border-radius: 0;
}
.ant-drawer-close {
padding: 0px;
}
}
.lightMode {
.ant-drawer-header {
border-bottom: 1px solid var(--bg-vanilla-400);
background: var(--bg-vanilla-100);
}
.log-detail-drawer {
.title {
color: var(--text-ink-300);
}
.log-detail-drawer__log {
.log-overflow-shadow {
background: linear-gradient(
270deg,
var(--bg-vanilla-100) 10.4%,
rgba(255, 255, 255, 0) 100%
);
}
.log-type-indicator {
border: 2px solid var(--bg-vanilla-400);
}
.ant-typography {
color: var(--text-ink-300);
background: transparent;
}
}
.radio-button {
border: 1px solid var(--bg-vanilla-400);
background: var(--bg-vanilla-100);
color: var(--text-ink-300);
}
.views-tabs {
.tab {
background: var(--bg-vanilla-100);
}
.selected_view {
background: var(--bg-vanilla-300);
border: 1px solid var(--bg-slate-300);
color: var(--text-ink-400);
}
.selected_view::before {
background: var(--bg-vanilla-300);
border-left: 1px solid var(--bg-slate-300);
}
}
.tabs-and-search {
.action-btn {
border: 1px solid var(--bg-vanilla-400);
background: var(--bg-vanilla-100);
color: var(--text-ink-300);
}
}
.search-input {
border: 1px solid var(--bg-vanilla-200);
background: var(--bg-vanilla-100);
color: var(--text-ink-300);
}
}
}

View File

@@ -0,0 +1,10 @@
.query-builder-search-wrapper {
margin-top: 10px;
height: 46px;
border: 1px solid var(--bg-slate-400);
border-bottom: none;
.ant-select-selector {
border: none !important;
}
}

View File

@@ -0,0 +1,77 @@
import './QueryBuilderSearchWrapper.styles.scss';
import useInitialQuery from 'container/LogsExplorerContext/useInitialQuery';
import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch';
import { Dispatch, SetStateAction, useEffect } from 'react';
import { ILog } from 'types/api/logs/log';
import { Query, TagFilter } from 'types/api/queryBuilder/queryBuilderData';
function QueryBuilderSearchWrapper({
log,
filters,
contextQuery,
isEdit,
suffixIcon,
setFilters,
setContextQuery,
}: QueryBuilderSearchWraperProps): JSX.Element {
const initialContextQuery = useInitialQuery(log);
useEffect(() => {
setContextQuery(initialContextQuery);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const handleSearch = (tagFilters: TagFilter): void => {
const tagFiltersLength = tagFilters.items.length;
if (
(!tagFiltersLength && (!filters || !filters.items.length)) ||
tagFiltersLength === filters?.items.length ||
!contextQuery
)
return;
const nextQuery: Query = {
...contextQuery,
builder: {
...contextQuery.builder,
queryData: contextQuery.builder.queryData.map((item) => ({
...item,
filters: tagFilters,
})),
},
};
setFilters({ ...tagFilters });
setContextQuery({ ...nextQuery });
};
// eslint-disable-next-line react/jsx-no-useless-fragment
if (!contextQuery || !isEdit) return <></>;
return (
<QueryBuilderSearch
query={contextQuery?.builder.queryData[0]}
onChange={handleSearch}
className="query-builder-search-wrapper"
suffixIcon={suffixIcon}
/>
);
}
interface QueryBuilderSearchWraperProps {
log: ILog;
isEdit: boolean;
contextQuery: Query | undefined;
setContextQuery: Dispatch<SetStateAction<Query | undefined>>;
filters: TagFilter | null;
setFilters: Dispatch<SetStateAction<TagFilter | null>>;
suffixIcon?: React.ReactNode;
}
QueryBuilderSearchWrapper.defaultProps = {
suffixIcon: undefined,
};
export default QueryBuilderSearchWrapper;

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