Compare commits

...

305 Commits

Author SHA1 Message Date
Prashant Shahi
dba4e00b02 chore(release): 📌 pin versions: SigNoz 0.22.0
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-07-06 00:06:37 +05:30
dnazarenkoo
8363dadd8d fix: resolve the list view issues (#3020)
* feat: add dynamic table based on query

* feat: add the list view for the traces explorer

* fix: fix the options menu

* feat: update the list view columns config for the traces explorer

* feat: fix columns for the list view for the traces explorer page

* feat: update customization columns for the list view from the traces explorer

* feat: add error msg for the list view, fix creating data for the table

* fix: resolve the list view issues

* fix: update the date column for the list view

* fix: remove additional filter title for the list view

* fix: add initial orderBy filter for the list view

---------

Co-authored-by: Yevhen Shevchenko <y.shevchenko@seedium.io>
Co-authored-by: Nazarenko19 <danil.nazarenko2000@gmail.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-07-05 16:20:20 +05:30
Srikanth Chekuri
b1c1a95e29 feat: update default logs page size (#3030) 2023-07-05 13:46:43 +05:30
dnazarenkoo
5540692500 feat: add the list view for the traces explorer (#2947)
* feat: add dynamic table based on query

* feat: add the list view for the traces explorer

* fix: fix the options menu

* feat: update the list view columns config for the traces explorer

* feat: fix columns for the list view for the traces explorer page

* feat: update customization columns for the list view from the traces explorer

* feat: add error msg for the list view, fix creating data for the table

---------

Co-authored-by: Yevhen Shevchenko <y.shevchenko@seedium.io>
Co-authored-by: Nazarenko19 <danil.nazarenko2000@gmail.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-07-05 12:51:22 +05:30
Vishal Sharma
2722538e82 Fix/handle hypen attributes (#3023)
* fix: handle attributes with hypen `-`

* test: update tests

* fix: only use backticks on columns orderby
2023-07-05 11:20:46 +05:30
Srikanth Chekuri
b8aba4f935 fix: alert evaluation params and query (#3010)
* fix: alert evaluation params and query
1. Update the rate query to not generate intermediary +inf value when the denominator is zero
2. Adjust the start and end time to incorporate data in movement
3. Round the start and end to minute
4. Add log to find the exact query that triggered alert for troubleshooting
;

* chore: fix query builder tests
2023-07-05 10:34:07 +05:30
Yevhen Shevchenko
ea89433dc0 fix: formula for table (#3004)
* fix: formula for table

* fix: empty column

* fix: formula values in table view

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-07-05 10:21:31 +05:30
Sachin M K
22bbfaf495 fix: dashboard query stuck on disabled (#2991)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-07-05 09:34:20 +05:30
Vishal Sharma
bc400c2bcf feat: trace view and list view for traces (#2847)
* feat: checkpoint

* feat: add select columns support to list view

* chore: add more error handling

* feat: always return timestamp, spanID, traceID
Always return timestamp, spanID, traceID in list view

* test: update and add new tests

* chore: remove deprecated const

* chore: addressed review comments

* fix: add support for timestamp ordering and fix logic related to timestamp orderBy

* chore: remove unused variable

* fix: edge case and more tests
2023-07-05 06:57:39 +05:30
Srikanth Chekuri
b7c50cc76d feat: add time support in formula (#2961) 2023-07-04 19:59:36 +05:30
Nityananda Gohain
193b04ff0f feat: minor fixes to logs QB (#3022)
* feat: minor fixes to logs QB

* fix: panel type check added

* fix: panel type check added

* fix: order by logic updated
2023-07-04 19:05:20 +05:30
dnazarenkoo
10a3a6d3e5 feat: add the traces view for the traces explorer (#2966)
* feat: add dynamic table based on query

* feat: add the list view for the traces explorer

* feat: add the list view for the traces explorer

* feat: add the list view for the traces explorer

* feat: add the table view for the traces explorer

* feat: add the table view for the traces explorer

* feat: add the trace view for the traces explorer

* feat: update the traces view tab for the traces explorer page

* feat: update the traces view

---------

Co-authored-by: Yevhen Shevchenko <y.shevchenko@seedium.io>
Co-authored-by: Nazarenko19 <danil.nazarenko2000@gmail.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-07-04 10:54:34 +05:30
dnazarenkoo
78da014b52 fix: remove the second action button in the dashboards table (#3012) 2023-07-04 09:50:12 +05:30
Srikanth Chekuri
20e71ec08a fix: add support for {max/min/avg} of rate (#2951) 2023-07-03 13:30:37 +05:30
Palash Gupta
cda37b99b4 feat: create alerts is updated from trace explorer (#2995) 2023-06-30 11:18:12 +05:30
Vishal Sharma
709bfda0cc fix: trace column attributes (#3000) 2023-06-30 10:55:45 +05:30
Srikanth Chekuri
20687d5184 feat: ability to configure noisy top level operations to discard (#2978) 2023-06-30 06:58:22 +05:30
Yevhen Shevchenko
0f998a4845 feat: add custom orderBy (#2975)
* feat: add custom orderBy

* chore: magic string is removed

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-29 21:19:56 +05:30
Palash Gupta
3464b2a59c feat: added time series tab in logs explorer (#2982) 2023-06-29 14:22:55 +05:30
GitStart
64d4532a6b feat: sort logs in ascending order (#2895)
* feat: sort logs in ascending order

Co-authored-by: gitstart <gitstart@gitstart.com>
Co-authored-by: Rubens Rafael <70234898+RubensRafael@users.noreply.github.com>
Co-authored-by: RubensRafael <rubensrafael2@live.com>

* refactor: requested changes

Co-authored-by: Nitesh Singh <nitesh.singh@gitstart.dev>
Co-authored-by: niteshsingh1357 <niteshsingh1357@gmail.com>
Co-authored-by: RubensRafael <rubensrafael2@live.com>

* fix: lint

Co-authored-by: niteshsingh1357 <niteshsingh1357@gmail.com>
Co-authored-by: Nitesh Singh <nitesh.singh@gitstart.dev>
Co-authored-by: RubensRafael <rubensrafael2@live.com>

* chore: removed the magic string

---------

Co-authored-by: gitstart <gitstart@users.noreply.github.com>
Co-authored-by: gitstart <gitstart@gitstart.com>
Co-authored-by: Nitesh Singh <nitesh.singh@gitstart.dev>
Co-authored-by: Rubens Rafael <70234898+RubensRafael@users.noreply.github.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
Co-authored-by: RubensRafael <rubensrafael2@live.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
Co-authored-by: niteshsingh1357 <niteshsingh1357@gmail.com>
2023-06-29 14:11:49 +05:30
dnazarenkoo
1eabacbaf4 feat: add the export panel to the traces explorer (#2983)
* feat: add the export panel to the traces explorer

* feat: onExport dashboard widget is updated

* chore: made common hook useDashboard

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-28 18:25:20 +05:30
Palash Gupta
9b8f7a091c fix: step size is made dynamic (#2903)
* fix: step size is made dynamic

* test: get step test is added

* chore: alerts step is updated

* chore: query is updated

* chore: provider query is updated

* fix: user input is being take care of

* chore: query builder step interval is updated

* test: lib/getStep is updated

* test: test for getStep is updated

* fix: step interval is taken care when we change from top nav

* chore: while saving the dashboard query is updated

* chore: updated when selected widget is present

* chore: getStep is now multiple of 60 and test is updated accordingly

* chore: user input is overriden from global step

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-06-28 15:19:52 +05:30
dnazarenkoo
56402b0d40 feat: add the url pagination & update options menu (#2943)
* feat: add dynamic table based on query

* fix: group by repeating

* fix: change view when groupBy exist in the list

* fix: table scroll

* feat: add the pagination and update options menu

* feat: trace explorer is updated

---------

Co-authored-by: Yevhen Shevchenko <y.shevchenko@seedium.io>
Co-authored-by: Nazarenko19 <danil.nazarenko2000@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-24 00:09:59 +05:30
Yevhen Shevchenko
bd18eee662 Fix/query builder updating (#2962)
* feat: add dynamic table based on query

* fix: group by repeating

* fix: change view when groupBy exist in the list

* feat: add list view for log explorer

* fix: query builder updating

* fix: table scroll

* fix: filters for explorer page (#2959)

---------

Co-authored-by: Prashant Shahi <prashant@signoz.io>
2023-06-23 13:49:53 +05:30
Yevhen Shevchenko
522bdf04ef feat: Add Generic Table View in the logs explorer (#2936)
* feat: add dynamic table based on query

* fix: group by repeating

* fix: change view when groupBy exist in the list

* fix: table scroll

* fix: filters for explorer page (#2959)

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-23 12:45:09 +05:30
Rajat Dabade
314edaf1df fix: default as query builder when creating new alert (#2963) 2023-06-23 11:22:34 +05:30
Rajat Dabade
c05c939ee1 feat: sorting for tooltip in graph view (#2948)
* feat: sorting for tooltip in graph view

* Update index.tsx

* refactor: name of the variable in itemSort

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-22 17:58:56 +05:30
Prashant Shahi
555bb79866 chore: 🔧 use signoz/locust docker repo for multi-arch image (#2954) 2023-06-22 15:00:31 +05:30
Ankit Nayan
2ee7817685 Merge pull request #2955 from SigNoz/release/v0.21.0
Release/v0.21.0
2023-06-22 00:56:11 +05:30
Prashant Shahi
803cfd1aa3 Merge branch 'develop' into release/v0.21.0 2023-06-22 00:30:02 +05:30
Palash Gupta
1c98d4f55c fix: editing condition is updated (#2952)
* fix: save rules/dashboard is now enabled for metrics irrespective of feature flag disabled

* chore: check is updated for alerts

* chore: alert condition is updated

* chore: condition for alert is updated

* fix: edit condition is fixed

* fix: isTraceOrLogsQueryBuilder condition for editing a panel

* fix: error message is shown to the user

---------

Co-authored-by: makeavish <makeavish786@gmail.com>
2023-06-21 20:56:15 +05:30
Srikanth Chekuri
4460b46e47 chore: bump SigNoz and collector versions 2023-06-21 20:07:49 +05:30
Palash Gupta
a6237d8640 fix: save rules/dashboard is now enabled for metrics irrespective of feature flag disabled (#2946)
* fix: save rules/dashboard is now enabled for metrics irrespective of feature flag disabled

* chore: check is updated for alerts

* chore: alert condition is updated

* chore: condition for alert is updated
2023-06-21 19:56:57 +05:30
Palash Gupta
3f4cd130ed fix: feature flag is added when we are switching the tab (#2930) 2023-06-21 16:46:11 +05:30
Palash Gupta
cf05345ccd fix: white screen issue is fixed when cloning the panel (#2944) 2023-06-21 13:33:06 +05:30
Vishal Sharma
9e305cb672 feat: add zap otel logger support (#2790)
* feat: add zap otel logger support
2023-06-21 11:47:30 +05:30
Rajat Dabade
0d82a93f18 fix: fixed the initial graph load issue for dashboard (#2938) 2023-06-20 09:07:19 +05:30
dnazarenkosignoz
96b94a619e feat: add the export panel (#2925)
* feat: add the export panel

* feat: dropdown overlay is updated to dropdown

* chore: loading variable is updated for create dashboard

* chore: export panel is updated

---------

Co-authored-by: Nazarenko19 <danil.nazarenko2000@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-19 19:07:44 +05:30
dnazarenkosignoz
37fc00b55f feat: add the Trace Explorer page with Query Builder (#2843)
* feat: update the SideNav component

* feat: add the Trace Explorer page with Query Builder

* chore: build is fixed

* chore: tsc build is fixed

* chore: menu items is updated

---------

Co-authored-by: Nazarenko19 <danil.nazarenko2000@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-19 18:27:58 +05:30
Palash Gupta
b782bd8909 chore: try signoz cloud link is updated (#2928) 2023-06-19 12:15:57 +05:30
Prashant Shahi
bcacb1d2b0 ci(gh-workflows): 👷 bump up versions and minor updates (#2923)
* ci(gh-workflows): 👷 bump up versions and minor updates

* ci(gh-workflows): 👷 bump up versions of verify-linked-issue-action to v0.71

* ci(e2e-k3s): 👷 use ipconfig instead

* ci(remove-label): 👷 create separate step for remove label

---------

Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-06-16 22:22:11 +05:30
Yevhen Shevchenko
7f05ce3d05 fix: query operator (#2924) 2023-06-16 18:10:54 +05:30
Yevhen Shevchenko
5bdb0e84d1 Feat/logs explorer (#2905)
* feat: add query builder and graph

* feat: add graph

* fix: id in the another places

* fix: multiple queries for explorer logs

* chore: chunkName is updated

---------

Co-authored-by: Chintan Sudani <46838508+techchintan@users.noreply.github.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-16 16:08:39 +05:30
Prashant Shahi
82936f73a3 chore: update Makefile (#2917)
* fix(docker-buildkit): 🐛 use progress plain

* chore(Makefile): add targets for clearing only clickhouse data

---------

Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-06-16 00:06:01 +05:30
Palash Gupta
9aa8148269 fix: updating dashboard variables is not allowed for viewer role (#2910)
Co-authored-by: Prashant Shahi <prashant@signoz.io>
2023-06-15 19:46:08 +05:30
Rajat Dabade
86c6c43f95 fix: updated redirect link for try signoz cloud button (#2919)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-15 17:48:55 +05:30
Palash Gupta
3792f137fa fix: new widget condition is fixed and handling of undefined is done (#2906) 2023-06-15 14:13:58 +05:30
Palash Gupta
389385324f fix: clone panel permission is updated (#2915) 2023-06-15 12:52:31 +05:30
Palash Gupta
9ad17c2d60 fix: handling of 404 in dashboard is updated (#2908) 2023-06-15 11:15:25 +05:30
Palash Gupta
52a222e87a feat: added the contribution guidelines (#2850) 2023-06-14 20:11:40 +05:30
Chintan Sudani
8433d81dc0 fix: alert name required message & button disabled (#2896)
* fix: alert name required message & button disabled

* fix: tooltip message issue

* fix: button disabled issue while create alert

* chore: requiredMessage is updated

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-14 12:53:50 +05:30
Palash Gupta
148889e198 fix: query key is updated (#2894) 2023-06-13 16:26:12 +05:30
GitStart
a649ced337 chore: alert rules is updated (#2646)
Co-authored-by: gitstart <gitstart@users.noreply.github.com>
Co-authored-by: niteshsingh1357 <niteshsingh1357@gmail.com>
Co-authored-by: Nitesh Singh <nitesh.singh@gitstart.dev>
Co-authored-by: Rubens Rafael <70234898+RubensRafael@users.noreply.github.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-13 14:15:52 +05:30
Daman Arora
3ba8ee1d26 fix: close dropdown after user has selected a tag (#2892)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-13 11:08:45 +05:30
Nityananda Gohain
316cbe484b fix: support for exists and nexists in existing parser (#2873)
* fix: support for exists and nexists in existing parser

* fix: comment updated

* feat: handle static log fields in exists and nexists
2023-06-13 09:49:23 +05:30
Palash Gupta
ef74ef3526 fix: sorting logic is updated (#2882)
* fix: sorting logic is updated

* fix: made a util for error rate

* chore: updated the function name
2023-06-12 18:19:07 +05:30
Chintan Sudani
bd6745dd66 fix: alert threshold disappears on run query (#2888)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-12 14:48:01 +05:30
Daman Arora
754ba93df9 fix: create and store label when colon is pressed (#2886)
* fix: create and store label when colon is pressed

* fix: use native JS replace

* chore: extra value variable is removed

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-12 14:36:21 +05:30
Pranay Prateek
bb7ea8e8fb Merge branch 'main' into develop 2023-06-09 19:38:26 +05:30
Prashant Shahi
4a467435e9 Merge pull request #2884 from SigNoz/release/v0.20.2
Release/v0.20.2
2023-06-09 17:42:04 +05:30
Nityananda Gohain
014d4a2e7c Fixes for pagination in listview (#2791) 2023-06-09 17:07:45 +05:30
Srikanth Chekuri
84c4668b67 chore: pin SigNoz version to 0.20.2 2023-06-09 14:20:15 +05:30
Srikanth Chekuri
0cf56d8247 fix: allow unspecified key type 2023-06-09 14:18:48 +05:30
Palash Gupta
99f863f444 fix: raw query is updated to query (#2881) 2023-06-09 14:17:23 +05:30
Palash Gupta
f3e077ce52 fix: raw query is updated to query (#2881) 2023-06-09 14:14:23 +05:30
Palash Gupta
5af5cb0cf0 FE: invite form is reset when closed (#2875)
* feat: add the options menu

* fix: data is reset when modal is turned down

---------

Co-authored-by: Palash <palashgdev@gmail.com>
2023-06-09 00:44:25 +05:30
Srikanth Chekuri
04a9de1e32 feat: add querier interface and initial implementation (#2782) 2023-06-08 15:46:18 +05:30
dnazarenkosignoz
7415de4751 feat: add the options menu (#2832)
Co-authored-by: Nazarenko19 <danil.nazarenko2000@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-08 14:50:39 +05:30
Chintan Sudani
e5bb125a55 fix: layout issue on alert page (#2867) 2023-06-08 13:49:01 +05:30
dnazarenkosignoz
540568d29f feat: update the SideNav component (#2858)
* feat: update the SideNav component

* chore: onClick is updated

* chore: selected condition is updated

* fix: build is fixed

---------

Co-authored-by: Nazarenko19 <danil.nazarenko2000@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-08 13:19:33 +05:30
Srikanth Chekuri
4d59f4c7e5 chore: pin SigNoz version to 0.20.1 2023-06-08 12:31:07 +05:30
Nityananda Gohain
59025238b3 fix: if condition corrected in aggreagte attribute static fields (#2866) 2023-06-08 12:29:18 +05:30
Nityananda Gohain
a67d064418 fix: if condition corrected in aggreagte attribute static fields (#2866) 2023-06-08 12:26:59 +05:30
Yevhen Shevchenko
1770e6a157 refactor: query data field for widgets (#2839)
* refactor: query data field for widgets

* fix: query key index

* fix: remove queryData fields

* fix: remove rest queryData field

* fix: remove queryData from services

* fix: remove queryData in another places

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-07 17:57:33 +05:30
Ankit Nayan
ef1bc0beec Merge pull request #2856 from SigNoz/release/v0.20.0
Release/v0.20.0
2023-06-07 16:50:33 +05:30
Srikanth Chekuri
b62b3591af chore: pin SigNoz version to 0.20.0 2023-06-07 15:48:23 +05:30
Chintan Sudani
97207f8e6d feat: added option to download logs in csv & excel format (#2841)
* feat: added option to download logs in csv format

* fix: suggested changes

* feat: added logs download as excel

* fix: updated logic for download excel and suggested changes

* fix: code level changes

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-06-07 15:31:57 +05:30
Srikanth Chekuri
745626f516 feat: add measurement value formatter (#2773) 2023-06-07 12:10:05 +05:30
GitStart
826cbe0803 feat: ability to clone a panel (#2444)
Co-authored-by: gitstart <gitstart@users.noreply.github.com>
Co-authored-by: Nitesh Singh <nitesh.singh@gitstart.dev>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
Co-authored-by: Prashant Shahi <prashant@signoz.io>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-06-07 10:50:01 +05:30
Yevhen Shevchenko
342e94d093 fix: query builder edit mode doesn't send correct payload (#2804)
* fix: where clause getting values

* fix: group by filter custom option

* fix: id for group by and aggregate filters

* fix: repeating values

* refactor: group by uniq items

* fix: removing source key

* fix: keep where clause filter on operator change

* chore: clean up for console log and additional variables

---------

Co-authored-by: Chintan Sudani <46838508+techchintan@users.noreply.github.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-07 00:58:18 +05:30
Srikanth Chekuri
6614cd31c1 feat: add cache interface and implementation for redis,inmemory (#2155) 2023-06-06 18:42:04 +05:30
Srikanth Chekuri
7086f7eafa feat: add measurement unit converter (#2772) 2023-06-06 18:29:56 +05:30
Srikanth Chekuri
edf7e9821f chore: update .github/CODEOWNERS (#2835)
* chore: update .github/CODEOWNERS

* chore: fix syntax

* Update .github/CODEOWNERS

Co-authored-by: Prashant Shahi <prashant@signoz.io>

---------

Co-authored-by: Prashant Shahi <prashant@signoz.io>
2023-06-06 18:18:06 +05:30
Srikanth Chekuri
a52c104562 fix: remove the top 10 limit on key operations table (#2824)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-06-06 17:25:53 +05:30
Vishal Sharma
a3c917cca0 fix: add legend property to Queries (#2821) 2023-06-06 06:05:48 +05:30
Palash Gupta
e73432df83 fix: org name is fixed (#2810) 2023-06-05 14:19:27 +05:30
Palash Gupta
d2cdf401b8 fix: alerts page threshold only number is allowed (#2816) 2023-06-05 12:42:38 +05:30
Palash Gupta
9091b9b82c fix: sorter is updated for sorting in alerts page (#2818) 2023-06-05 12:13:24 +05:30
Palash Gupta
c69e2e0d50 fix: limit default value is updated (#2805) 2023-06-01 23:34:32 +05:30
Yevhen Shevchenko
ad5a9dcd6a feat: add share url (#2778)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-06-01 22:47:09 +05:30
Palash Gupta
7fd27ec09d fix: service name capitalisation is removed from list page (#2806) 2023-06-01 00:56:03 +05:30
Vishal Sharma
26a806a7fe fix: mutex lock to avoid concurrent map writes (#2796) 2023-05-31 11:27:09 +05:30
Yevhen Shevchenko
bc5862646d fix: where clause filter (#2800) 2023-05-30 20:53:11 +05:30
chaks
eb1c5c4565 fix: typo in contribution guide (#2792)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-30 05:50:35 +05:30
Janssen
fdbb8b652e Nit: fix typo in install script. (#2793) 2023-05-29 18:30:32 +05:30
Nityananda Gohain
7f9c226175 feat: formatter updated (#2780)
* feat: formatter updated

* feat: formatter updated with all int types
2023-05-26 11:32:39 +05:30
Nityananda Gohain
b9c87c1395 feat: support for top level keys in attributes in query parser logs v3 (#2753)
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-05-25 09:58:32 +05:30
GermaVinsmoke
708f6dd03f chore: added disabled property to the btn (#2775)
Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>
2023-05-24 16:50:09 +05:30
Palash Gupta
2f27908434 test: some of the test case is added (#2607)
* test: some of the test case is added

* fix: build is fixed

* chore: tsc is fixed

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-05-24 15:21:30 +05:30
GermaVinsmoke
234a69de8c feat: moved invite members form to antd form (#2745)
* feat: moved invite members form to antd form

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

* chore: center align add more btn

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

* chore: name optional, space proper alignment

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

* chore: used lib fn for require message

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

---------

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-24 11:47:21 +05:30
GermaVinsmoke
fda0441686 feat: moved apply license form to antd form (#2746)
* feat: moved apply license form to antd form

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

* chore: added lib fn for require error msg

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

---------

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>
2023-05-23 23:14:02 +05:30
GermaVinsmoke
b034c60897 chore: form changes (#2754)
* chore: form type and removed disabled

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

* chore: added disabled to the button

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

* chore: created error message fn for required rule

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

* chore: disable condition is updated

* chore: isLoading is added in the disabled condition

---------

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-23 21:56:06 +05:30
Palash Gupta
5a81f5f90b fix: cloud header button is hidden when is license is not active (#2756) 2023-05-23 19:29:24 +05:30
Yevhen Shevchenko
818a984af3 Feat/extend query builder state (#2755)
* feat: extends query builder state

* fix: correct import path for query type
2023-05-23 19:17:52 +05:30
Ankit Nayan
1ded475b37 Merge pull request #2739 from SigNoz/release/v0.19.0
Release/v0.19.0
2023-05-21 01:39:55 +05:30
Prashant Shahi
6e8be3fcc3 Merge branch 'main' into release/v0.19.0 2023-05-20 23:13:31 +05:30
Prashant Shahi
182ba3596d chore: 📌 pin versions: SigNoz 0.19.0, SigNoz OtelCollector 0.76.1
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-05-20 23:10:02 +05:30
Palash Gupta
ef6d847c15 chore: remove the limit condition (#2737) 2023-05-20 10:42:40 +05:30
Yevhen Shevchenko
6e2ceb9efb fix: alerts formula (#2733)
* fix: alerts formula

* fix: use formula regexp

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-05-19 19:31:04 +05:30
Palash Gupta
02035ebd82 fix: query key is made dyanmic (#2735) 2023-05-19 19:04:41 +05:30
Palash Gupta
cf95d9c76f fix: remove some of the frontend redundant packages (#2731)
* test: added few test cases for Tooltip

* fix: some of the stale frontend package are removed

* chore: flat package is removed

---------

Co-authored-by: Sanjib <sanjib.sah@yahoo.com>
2023-05-19 17:42:20 +05:30
Palash Gupta
9ff055015f fix: commit lint is updated (#2732)
* fix: commit lint is updated

* chore: command is updated

* chore: added dummy commit message

* chore: updated the github actions
2023-05-19 17:17:13 +05:30
Sanjib Kumar Sah
e2ce1eb88b Test: added few test cases for Tooltip (#2714)
* test: added few test cases for Tooltip

* Update TextToolTip.test.tsx

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-19 15:37:23 +05:30
Nityananda Gohain
5a00fbd1d2 feat: add default parser for logs (#2701)
* feat: add default parser for logs

* fix: change name to internal
2023-05-19 14:11:09 +05:30
Sanjib Kumar Sah
a047801014 Test: added few test cases for MessageTip (#2715)
* test: added few test cases for MessageTip

* chore: test is fixed

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-19 13:42:14 +05:30
GermaVinsmoke
72452dc946 chore: remove react import (#2727)
* chore: added jsx-runtime plugin in eslint tsconfig

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

* chore: updated react imports

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

* chore: renamed redux dispatch

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>

* fix: build is fixed

---------

Signed-off-by: GermaVinsmoke <vaibhav1180@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-19 13:14:32 +05:30
Palash Gupta
604d98be05 feat: feature flag is updated (#2666)
* feat: flag is updated

* feat: feature flag is updated

* feat: onrefetch is added on several actions on app

* chore: tab is updated

* chore: creating dashbaord error is handled

* fix: message is fixed

* chore: jest test is updated
2023-05-19 12:19:42 +05:30
Sanjib Kumar Sah
e7f5adc8a9 Fix: disabled content being copied on keyDown action (#2716)
* fix: disabled content being copied on keyDown action

* chore: tab index and role is updated

* fix: reverted lodash changes

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-19 11:58:01 +05:30
Yevhen Shevchenko
fb10d7d81f fix: onBlur for groupBy (#2728) 2023-05-18 21:49:11 +05:30
Vishal Sharma
d67f709b8a fix: add validations for aggregates on logs/traces datasource (#2709) 2023-05-18 17:16:06 +05:30
Yevhen Shevchenko
81291c996f fix: api calls (#2725)
* fix: aggregate filter and group by filter

* fix: operators labels and divider

* fix: api calls

* fix: remove ts ignore from file
2023-05-18 17:01:50 +05:30
Yevhen Shevchenko
18fc1a2761 fix: having filter removing payload (#2706) 2023-05-18 16:44:34 +05:30
Pranay Prateek
679eb39256 Update README.md (#2724)
Removed icons which were in AWS S3
2023-05-18 16:02:16 +05:30
Vishal Sharma
357e422eca fix: add support for bool values in time series result (#2713)
* fix: add support for bool values in time series result

* chore: reserved target column can never be bool so removed obsolete code

---------

Co-authored-by: Ankit Nayan <ankit@signoz.io>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-18 14:08:32 +05:30
Chintan Sudani
ca3ff04f7d fix: issue of new query builder v3 (#2697)
* fix: position of where caluse is changed for metrics

* fix: by default enabled for logs & traces

* fix: to many api call for key on search

* fix: make chip on enter for exists/nexists

* fix: flickering issue on selection of option

* fix: text change

* fix: orderby payload issue

* fix: removed replace logic

* fix: responsive qb & disabled issue

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
Co-authored-by: Ankit Nayan <ankit@signoz.io>
2023-05-18 12:55:18 +05:30
Palash Gupta
a0c320e47e feat: trace to logs and logs to trace is added (#2699)
* feat: trace to logs and logs to trace is added

* chore: icons and spanId is updated

* chore: feedback changes are updated

---------

Co-authored-by: Ankit Nayan <ankit@signoz.io>
2023-05-18 12:36:02 +05:30
Srikanth Chekuri
5637188e72 chore: commit lock file (#2718)
* chore: commit lock file

* chore: update frontend/Dockerfile
2023-05-18 12:23:40 +05:30
Vishal Sharma
7cb2399c4c fix: feature usage count (#2710) 2023-05-17 20:24:10 +05:30
Srikanth Chekuri
93c9138fe1 fix: update the resource detection processor name for GCP (#2679) 2023-05-17 18:24:00 +05:30
Nityananda Gohain
d1a256a6d5 feat: don't throw error if unable to enrich metadata (#2608)
* feat: don't throw error is unable to enrich metadata

* feat: remove isDefaultEnriched key

* feat: validate and cast added

* feat: function name corrected

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-05-17 16:57:04 +05:30
Palash Gupta
b6a455d264 feat: add signoz cloud button in header (#2694)
* feat: add signoz cloud button in header

* chore: gap is updated

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-05-17 16:24:16 +05:30
Vishal Sharma
c32b8638a4 feat: introduce feature_usage table to manage features (#2661)
* feat: introduce feature_usage table to manage features
* feat: introduce limit on QB alerts and dashboards
2023-05-17 16:10:43 +05:30
Prashant Shahi
e21f23874d fix(frontend): 🐛 accept zero as valid alert threshold (#2703) 2023-05-17 09:17:14 +05:30
ww9
43c05c9605 chore: fix small typo in README.md (#2667)
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
Co-authored-by: Prashant Shahi <prashant@signoz.io>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
Co-authored-by: Pranay Prateek <pranay@signoz.io>
2023-05-16 20:18:50 +05:30
Vishal Sharma
ec8e505647 fix: count fixed columns of type bool/number (#2698)
* fix: count fixed columns of type bool/number

* fix: add test for count with fixed column and filter
2023-05-16 19:32:50 +05:30
Palash Gupta
c7f09354f7 fix : parsing issue is fixed in the table view (#2693)
* fix: parsing is updated
2023-05-15 18:04:58 +05:30
Srikanth Chekuri
df0502726d fix: resolve gaps identified in the query builder (#2680) 2023-05-12 16:25:22 +05:30
Saurav Khdoolia
e8f2176566 fix: add isRefetching as spinner check to reset init values (#2671)
Signed-off-by: Saurav Kumar <sauravkhdoolia@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-12 13:41:04 +05:30
Yevhen Shevchenko
9da399023b refactor(query_builder): remove old codebase (#2686)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-12 13:21:59 +05:30
Chintan Sudani
76331001b7 fix: issues on WHERE search filter (#2629)
* fix: search filter validation on data source

* fix: value search not working for in/nin

* fix: unwanted key api while searching value & disabled tag

* fix: unnecessary , at end of in/nin value

* fix: added space after operator to get value

* fix: custom value not being selected

* fix: space after tag and value

* fix: api call debounce duration

* fix: suggested changes

* fix: updated query params

* fix: search filter data for logs and traces

* fix: search filter value data type issue

* fix: search filter value tag type

* fix: chip & iscolumn issue

* fix: null handled

* fix: label in list of search filter component

* fix: label in list of search filter component

* fix: code level changes

* fix: incorrect filter operators

* fix: key selection dancing

* fix: missing suggestion

* fix: keys are not getting updated

* fix: strange behaviour - removed duplicate options

* fix: driver id exclusion not working

* fix: loader when 0 options

* fix: exists/not-exists tag value issue

* fix: some weird behaviour about exists

* fix: added duplicate option remove logic at hook level

* fix: removed empty options from list

* fix: closable chip handler on edit

* fix: search filter validation on data source

* fix: value search not working for in/nin

* fix: unwanted key api while searching value & disabled tag

* fix: unnecessary , at end of in/nin value

* fix: added space after operator to get value

* fix: custom value not being selected

* fix: space after tag and value

* fix: api call debounce duration

* fix: suggested changes

* fix: updated query params

* fix: search filter data for logs and traces

* fix: search filter value data type issue

* fix: search filter value tag type

* fix: chip & iscolumn issue

* fix: null handled

* fix: label in list of search filter component

* fix: label in list of search filter component

* fix: code level changes

* fix: incorrect filter operators

* fix: key selection dancing

* fix: missing suggestion

* fix: keys are not getting updated

* fix: strange behaviour - removed duplicate options

* fix: driver id exclusion not working

* fix: loader when 0 options

* fix: exists/not-exists tag value issue

* fix: some weird behaviour about exists

* fix: added duplicate option remove logic at hook level

* fix: removed empty options from list

* fix: closable chip handler on edit

* fix: search filter validation on data source

* fix: lint issues is fixed

* fix: chip & iscolumn issue

* fix: lint changes are updated

* fix: undefined case handled

* fix: undefined case handled

* fix: removed settimeout

* fix: delete chip getting value undefined

* fix: payload correctness

* fix: incorrect value selection

* fix: key text typing doesn't change anything

* fix: search value issue

* fix: payload updated

* fix: auto populate value issue

* fix: payload updated & populate values

* fix: split value for in/nin

* fix: split value getting undefined

* fix: new version of search filter using papaparse library

* fix: removed unwanted space before operator

* fix: added exact find method & removed includes logic

* fix: issue when user create chip for exists not exists operator

* fix: white space logic removed

* fix: allow custom key in from list

* fix: issue when user create chip for exists not exists operator

* fix: removed unwanted includes

* fix: removed unwanted utils function

* fix: replaced join with papa unparse

* fix: removed get count of space utils

* fix: resolved build issue

* fix: code level fixes

* fix: space after key

* fix: quote a value if comma present

* fix: handle custom key object onchange

* chore: coverted into string

* Merge branch 'develop' into fix/issue-search-filter

* chore: eslint rule disabling is removed

* fix: serviceName contains sql

* chore: less restrictive expression

* fix: custom key selection issue

* chore: papa parse version is made exact

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-05-12 12:30:00 +05:30
Palash Gupta
10e47b5bff chore: removed some of the stage logic in the query builder (#2682) 2023-05-11 14:14:17 +05:30
Palash Gupta
25398d9d35 fix: query builder filter label is adopted for dark mode (#2683)
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2023-05-11 13:56:29 +05:30
Srikanth Chekuri
38bfc41190 fix: disable prometheus.NormalizeName flag (#2678) 2023-05-11 13:47:23 +05:30
Yevhen Shevchenko
8679f2c37a feat: add query builder to the alerts (#2657)
* fix: having value data type

* feat: connect new builder to dashboard

* Fix/query builder filters (#2623)

* feat: rename query data type

* fix: remove reset of groupBy

* fix: filters search

* fix: calls autocomplete times

* fix: response mapper

* fix: removee unnecessary field

* fix: no check ts types for old query builder

* fix: disable check utils old builder

* feat: add query builder to the alerts

* fix: alert response integration with query builder

* fix: validation of query builder rules

* fix: rules query builder

* fix: filter value with similar keys

* fix: null values for options

* fix: query builder disabled when exist formula

* fix: removing filter key with underscore

* feat: add builder data to metric application (#2665)

* feat: add builder data to metric application

* fix: query types to single variant

* fix: formula legend formatting

* fix: argumant name

* fix: date for graph

---------

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

* fix: pipeline

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-10 22:10:27 +05:30
Saurav Khdoolia
f7cd0d4934 [Fix]: Alert Channels breadcrumbs (#2669)
* fix: wrong routes in route constants file

* fix: add channels name in beradcrumb map

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-05-10 11:34:16 +05:30
Srikanth Chekuri
12349d79a9 feat(query-service): alerts integration with query builder v3 (#2663) 2023-05-09 19:16:55 +05:30
Srikanth Chekuri
c5991b50bc fix: nan aggregation values are ignored (#2664) 2023-05-08 18:07:26 +05:30
Vishal Sharma
8dbd1c65e9 fix: trim spaces from email invite (#2668) 2023-05-08 16:13:47 +05:30
Palash Gupta
2089c51f63 test: editor test case is added (#2649) 2023-05-03 00:26:06 +05:30
Palash Gupta
a021386cb8 test: added useIsValidTag.test (#2589)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-05-02 22:44:49 +05:30
Yevhen Shevchenko
8c2f33c95a feat: Connect Query builder with graph (#2611)
* fix: having value data type

* feat: connect new builder to dashboard

* Fix/query builder filters (#2623)

* feat: rename query data type

* fix: remove reset of groupBy

* fix: filters search

* fix: calls autocomplete times

* fix: response mapper

* fix: removee unnecessary field

* fix: no check ts types for old query builder

* fix: disable check utils old builder
2023-05-02 19:38:03 +05:30
Palash Gupta
bbda684e65 test: some of the test case is added (#2616)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-05-02 19:03:48 +05:30
Palash Gupta
37ff9480e1 test: dashboard variable is updated (#2640)
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-05-02 18:51:24 +05:30
Palash Gupta
fe314a8ddd feat: package dependency is made exact (#2644) 2023-05-02 11:39:01 +05:30
GermaVinsmoke
8bddee75a3 fix: changed versions of zookeeper & alertmanager (#2647) 2023-05-02 08:02:53 +05:30
Palash Gupta
a8eec1b7ab test: loadable component is added (#2650) 2023-05-01 18:42:44 +05:30
Palash Gupta
93220ba6c2 feat: error rate is added (#2638)
* feat: error rate is added

* fix: build is fixed

* chore: added the percentage sign
2023-04-27 17:17:15 +05:30
Srikanth Chekuri
f45ac7855e fix: update default pagerduty message (#2617) 2023-04-26 19:57:28 +05:30
Vishal Sharma
33ac5b79be feat: add errorCount in top_operations API (#2636) 2023-04-26 18:23:54 +05:30
Ankit Nayan
d5e112a9bc Merge pull request #2634 from SigNoz/release/v0.18.3
Release/v0.18.3
2023-04-26 16:51:41 +05:30
Palash Gupta
428b10f78c Merge branch 'main' into release/v0.18.3 2023-04-26 14:21:44 +05:30
Srikanth Chekuri
8824916880 Merge branch 'main' into release/v0.18.3 2023-04-26 14:21:41 +05:30
Srikanth Chekuri
b24fadaf86 chore: pin version 0.18.3 2023-04-26 14:13:54 +05:30
Palash Gupta
c149181924 fix: dashboard variable is fixed (#2633) 2023-04-26 13:57:54 +05:30
Palash Gupta
5ad367a0fc fix: dashboard variable is fixed (#2633) 2023-04-26 13:53:53 +05:30
Vishal Sharma
bd248c46b2 feat: traces QB (#2571) 2023-04-25 21:53:46 +05:30
Daniël
dcad77746a feat: added configuration via env for context timeout (#2585) 2023-04-25 16:29:49 +05:30
Chintan Sudani
b27bdac1f6 fix: Order By filter feedback on new QB (#2626)
* fix: removing key from groupby is not updating value of orderby

* fix: removing operator is not updating value of orderby

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-04-25 13:27:37 +05:30
Ankit Nayan
17438ca823 Merge pull request #2512 from SigNoz/issue-2511
chore: update pr_verify_linked_issue workflow
2023-04-25 11:34:28 +05:30
Prashant Shahi
684eeace93 Merge branch 'develop' into issue-2511 2023-04-25 11:06:26 +05:30
Chintan Sudani
bbffac1603 fix: Only positive integer values should be allowed for limit (#2619)
* fix: only positive number should accept on limit

* fix: suggested changes
2023-04-25 11:02:10 +05:30
Vishal Sharma
37493b49e5 Merge branch 'develop' into issue-2511 2023-04-25 00:52:06 +05:30
Prashant Shahi
3e97d2ffa3 feat(clickhouse): support for Google Cloud Storage (GCS) in Docker/Swarm (#2605)
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-04-24 21:37:33 +05:30
Vishal Sharma
e2df2e7c41 chore: validateAndCastValueData (#2610) 2023-04-24 20:38:08 +05:30
Prashant Shahi
6322578842 Merge branch 'develop' into issue-2511 2023-04-24 18:09:35 +05:30
Nityananda Gohain
21c6d3ba99 fix: remove log lines which doesn't contain the key while performing … (#2609)
* fix: remove log lines which doesn't contain the key while performing groupBy

* fix: print removed
2023-04-24 18:01:13 +05:30
Ankit Nayan
975d57cade Merge pull request #2613 from SigNoz/release/v0.18.2
Release/v0.18.2
2023-04-21 23:36:34 +05:30
Prashant Shahi
efe34d2582 Merge branch 'main' into release/v0.18.2 2023-04-21 15:05:17 +05:30
Prashant Shahi
d63a35e937 chore: 📌 pin versions: SigNoz 0.18.2
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-04-21 15:16:36 +05:45
Palash Gupta
c49bb0696b fix: clear filter is fixed (#2544)
* fix: clear filter is fixed

* chore: action bar empty query condition is handled

* feat: local state is clear for filters

(cherry picked from commit 6c11c6d4da)
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-04-21 15:12:36 +05:45
Palash Gupta
9a58cc652c feat: custom time frame is updated (#2564)
(cherry picked from commit fb1e823e6b)
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-04-21 15:09:35 +05:45
Palash Gupta
5ee0bb57cc fix: max depth issue is fixed in dashboard (#2563)
(cherry picked from commit 1726469aaa)
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-04-21 15:09:11 +05:45
Palash Gupta
6949c659af feat: resource attribute query is shared in the app navigation from sidebar (#2553) 2023-04-20 18:14:32 +05:30
Palash Gupta
6c11c6d4da fix: clear filter is fixed (#2544)
* fix: clear filter is fixed

* chore: action bar empty query condition is handled

* feat: local state is clear for filters
2023-04-20 17:28:35 +05:30
Nityananda Gohain
9557cb2f70 feat: handle static fields correcty in aggreagte attribute keys (#2598) 2023-04-20 13:09:32 +05:30
Chintan Sudani
2e4f0cfc33 fix: edit tag chip for WHERE clause updated logic (#2590)
* feat: edit search filter tag for query builder

* fix: edit tag updated logic

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-04-20 02:18:06 +05:30
Palash Gupta
ea6ee6a6ef fix: propswithchildren is removed (#2595) 2023-04-19 18:50:13 +05:30
Yevhen Shevchenko
dd25ad95c7 feat(builder): add having filter (#2567)
* feat(builder): add having filter

* feat(builder): add having filter

* feat(builder): add having filter

* feat: return initial query builder

* fix: having filter operators and values
2023-04-19 09:55:18 +05:30
Chintan Sudani
63570c847a feat: added Order By filter (#2551)
* fix: remove frontend code owner

* chore: set Cache-Control for auto complete requests (#2504)

* feat(filter): add group by filter (#2538)

* feat: poc of search bar

* feat: poc of search bar

* feat: attribute keys auto complete  api

* chore: conflict resolve

* chore: conflict resolve

* fix: menu was not open on click

* feat: re-used antoney's hooks code

* fix: linting & type issue

* fix: unwanted file changes

* fix: conflic changes

* feat: added orderby filter

* chore: rebased changes

* feat: poc of search bar

* feat: poc of search bar

* feat: attribute keys auto complete  api

* chore: conflict resolve

* fix: menu was not open on click

* feat: re-used antoney's hooks code

* fix: linting & type issue

* fix: uncomment qb component

* fix: unwanted file changes

* fix: conflic changes

* fix: suggested changes

* fix: reused label component

* fix: unwanted changes

* fix: unwanted changes

* fix: recovered old changes

* fix: orderby reset behaviour

* chore: rebased changes

* fix: resolved unwanted changes

* fix: ui of filter row

* fix: resolved order by filter issue on label

* fix: resolved reset behaviour

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
Co-authored-by: Yevhen Shevchenko <90138953+yeshev@users.noreply.github.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-04-18 17:17:06 +05:30
Vishal Sharma
60b78e94d8 fix: add support for count aggregate attribute (#2584) 2023-04-18 16:38:52 +05:30
Chintan Sudani
51f1d0fd05 feat: added aggregate every filter (#2581)
* fix: remove frontend code owner

* chore: set Cache-Control for auto complete requests (#2504)

* feat(filter): add group by filter (#2538)

* feat: added aggregate every filter

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
Co-authored-by: Yevhen Shevchenko <90138953+yeshev@users.noreply.github.com>
2023-04-18 11:44:28 +05:30
Chintan Sudani
502b8b1ba8 fix: tag filters query missing on page reload (#2580)
* fix: remove frontend code owner

* chore: set Cache-Control for auto complete requests (#2504)

* feat(filter): add group by filter (#2538)

* fix: tag filters query missing on page reload

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
Co-authored-by: Yevhen Shevchenko <90138953+yeshev@users.noreply.github.com>
2023-04-18 11:28:44 +05:30
Prashant Shahi
041d347d50 chore: 🔧 update install and troubleshooting guide url (#2451)
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-04-17 19:57:42 +05:30
Prashant Shahi
9aff047da4 chore: 🔧 remove resource requests/limits from sample apps (#2288)
Signed-off-by: Prashant Shahi <prashant@signoz.io>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
Co-authored-by: palashgdev <palashgdev@gmail.com>
2023-04-17 19:56:14 +05:30
Chintan Sudani
0bc44c6fd9 feat: Limt filter for QB (#2561) 2023-04-15 18:37:51 +05:30
Chintan Sudani
23081996c4 feat: Search bar for Query Builder (#2517) 2023-04-15 16:08:17 +05:30
Vishal Sharma
2c206e8bf4 Add Span attributes APIs (#2414) 2023-04-13 15:33:08 +05:30
Palash Gupta
1726469aaa fix: max depth issue is fixed in dashboard (#2563) 2023-04-12 14:00:52 +05:30
Palash Gupta
fb1e823e6b feat: custom time frame is updated (#2564) 2023-04-12 13:50:24 +05:30
Palash Gupta
813eeb6d5a test: metrics table test case is added (#2554) 2023-04-12 13:30:50 +05:30
Palash Gupta
a3bc2ff24e feat: signoz ui color hex support is added (#2560) 2023-04-11 12:32:12 +05:30
Nityananda Gohain
0c2574cef8 (logs): Query range v3 (#2518) 2023-04-10 19:36:13 +05:30
Yevhen Shevchenko
7c952fd9cd feat(builder): add additional filter toggler (#2549)
* feat(builder): add additional filter toggler

* feat(builder): add filters deps from another

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-04-10 17:32:45 +05:30
Ankit Nayan
9ac2308b89 Merge pull request #2528 from techchintan/fix/remove-fe-owner
fix: remove frontend code owner
2023-04-07 11:47:34 +05:30
Chintan Sudani
81beaffa3d Merge branch 'develop' into fix/remove-fe-owner 2023-04-07 11:07:15 +05:30
Srikanth Chekuri
4db109cbad fix: minor issues found in development and enhancements (#2542)
* temp commit

* chore: add setpInterval

* chore: update prepare func type
2023-04-07 09:46:21 +05:30
Chintan Sudani
5b72919a55 Merge branch 'develop' into fix/remove-fe-owner 2023-04-06 17:14:40 +05:30
Nityananda Gohain
d09290528f feat(logs): add tag attribute autocomplete for logs (#2404)
* chore: add payload types for autocomplete requests

* chore: update the query params file location and payload

* chore: add query range v3 API request/response payload types

* feat: metric attribute autocomplete for the aggregation type

* feat: add attrs filters autocomplete endpoints

* feat(logs): add tag attribute autocomplete for logs

* chore: added support for multiple datatype in value suggestion api for attributes

* feat: int64/float64 added for AttributeKeyDataType along with validation

* feat: filterAttributeValueResponse type updated

* fix: number type updated and query updated

* feat: remove tagType in keys autocomplete

* feat: return isColumn value correctly for attibute keys

* Update pkg/query-service/app/clickhouseReader/reader.go

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>

* fix: don't skip empty strings in value autocomplete

* fix: allow empty string search

* feat: add top level column names of logs in key sugestion

* fix: tagType column removed

* feat: get attribute values from logs table for top level fields

* feat: don't throw error if dataType and tagType is not present

* feat: timerange select corrected

* feat: autocomplete for int/float added

* fix: reverted attributeValueResponse change

* fix: null values handled for int and float

* feat: add support for get log aggreagte attributes

* feat: aggreate attribute logic updated and body added in keys autocomplete

* fix: constants updaetd

* fix: body type updated and empty response for noop and count

* fix: isColumn logic updated

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
Co-authored-by: palashgdev <palashgdev@gmail.com>
2023-04-06 13:32:24 +05:30
Chintan Sudani
7dd09129aa Merge branch 'develop' into fix/remove-fe-owner 2023-04-05 15:33:44 +05:30
Yevhen Shevchenko
5f73a82d9f feat(filter): add group by filter (#2538) 2023-04-05 15:02:15 +05:30
Srikanth Chekuri
d4bfe3a096 chore: set Cache-Control for auto complete requests (#2504) 2023-04-05 12:36:38 +05:30
Chintan Sudani
c92493904b Merge branch 'develop' into fix/remove-fe-owner 2023-04-04 16:56:14 +05:30
Palash Gupta
c74896b213 fix: cursor pointer is removed the table view (#2547) 2023-04-04 16:42:52 +05:30
Chintan Sudani
0b3e8d797b Merge branch 'develop' into fix/remove-fe-owner 2023-04-03 17:17:24 +05:30
Ankit Nayan
c8f3e9024c Merge pull request #2539 from SigNoz/release/v0.18.1
Release/v0.18.1
2023-04-03 16:19:24 +05:30
Prashant Shahi
8f6178f0a9 chore: 📌 pin versions: SigNoz 0.18.1
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-04-03 15:47:54 +05:45
Palash Gupta
5ff9172103 fix: slider duration is fixed (#2537) 2023-04-03 15:26:47 +05:30
Palash Gupta
67ba46abde fix: 2427 Latency graph onclick is updated (#2534) 2023-04-03 14:00:36 +05:30
Palash Gupta
20b1f96c19 fix: global time navigation is fixed (#2533) 2023-04-03 13:30:48 +05:30
Chintan Sudani
0e8f09632f Merge branch 'develop' into fix/remove-fe-owner 2023-04-03 09:37:30 +05:30
Yevhen Shevchenko
61a1d04252 feat(builder): add aggregator filter (#2516)
Co-authored-by: Chintan Sudani <46838508+techchintan@users.noreply.github.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-04-01 11:29:35 +05:30
Ankit Nayan
80171eddea Merge pull request #2531 from SigNoz/release/v0.18.0
Release/v0.18.0
2023-03-31 18:15:08 +05:30
Prashant Shahi
28684423d1 chore: 📌 pin versions: SigNoz 0.18.0, SigNoz OtelCollector 0.66.7
Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-03-31 16:59:21 +05:45
Chintan Sudani
a5e4336e18 Merge branch 'develop' into fix/remove-fe-owner 2023-03-31 14:43:58 +05:30
Palash Gupta
037559537b feat: keys for the service map is updated (#2525) 2023-03-31 12:59:57 +05:30
Chintan Sudani
c9db4c9051 Merge branch 'develop' into fix/remove-fe-owner 2023-03-31 12:10:11 +05:30
Nityananda Gohain
31a89bfdb3 fix: case sensitive selected field search fixed (#2529) 2023-03-31 11:58:58 +05:30
Chintan Sudani
776aa3471f fix: remove frontend code owner 2023-03-31 09:37:32 +05:30
Prashant Shahi
36610c809e CI: deployment workflow changes (#2527)
* chore: 📌 bump up appleboy/ssh-action to v0.1.8

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

* ci(deployments): 🔧 use SSH_KEY secret

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

* ci(staging-deployment): 👷 use main tag of OtelCollectors in Staging

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

---------

Signed-off-by: Prashant Shahi <prashant@signoz.io>
2023-03-30 23:57:29 +05:30
Palash Gupta
1a0c76a43b fix: min and max time is removed from the dependency list (#2522) 2023-03-30 16:16:46 +05:30
Palash Gupta
c1d00c1155 fix: dependecies is updated (#2510) 2023-03-29 18:55:30 +05:30
Palash Gupta
3f96325ad8 ability to filter by deployment environment service map (#2506) 2023-03-29 18:31:59 +05:30
Palash Gupta
99ed314fc9 feat: resource attribute is added in the exception (#2491)
* feat: resource attribute is added in the exception

* fix: build is fixed

* chore: methods is updated to post

* fix: build is fixed

* fix: listErrors, countErrors API request body

* chore: type of the function is updated

* chore: convertRawQueriesToTraceSelectedTags is updated

* fix: resource attribute is updated

* chore: selected tags is updated

* feat: key is updated

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-03-29 14:45:58 +05:30
Vishal Sharma
12e56932ee fix: exception detail broken APIs due to resourceTagsMap (#2514) 2023-03-29 07:32:47 +05:30
Srikanth Chekuri
c4944370ce feat: support environment filtering in service map (#2481) 2023-03-28 22:15:46 +05:30
Chintan Sudani
192d3881a1 fix: commented unwanted sidebar menu option (#2513)
* fix: Removed Strict mode to stop render twice

* fix: commented unwanted sidebar menuoption
2023-03-28 21:22:06 +05:30
Srikanth Chekuri
d6152510c7 Merge branch 'develop' into issue-2511 2023-03-28 06:09:02 +05:30
Srikanth Chekuri
3e37a8b364 chore: update version 2023-03-28 06:06:10 +05:30
Srikanth Chekuri
b9b63a0ac4 chore: update pr_verify_linked_issue workflow 2023-03-28 05:56:49 +05:30
Vishal Sharma
9d20c2f787 feat: add resource tags to ListErrors API (#2487) 2023-03-28 00:15:15 +05:30
Yevhen Shevchenko
8ea0f72178 feat(UI): add new query label (#2488) 2023-03-27 16:49:49 +05:30
Yevhen Shevchenko
167050b4b5 feat(provider): add base query types (#2501)
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-03-27 14:04:06 +05:30
Palash Gupta
fe640aae39 fix: label is added in the tabs (#2507) 2023-03-27 12:11:35 +05:30
Yevhen Shevchenko
6c2faa21f4 fix(query): change correct position of provider (#2498) 2023-03-24 18:16:28 +05:30
Yevhen Shevchenko
c617784d7c feat(provider): add query builder provider (#2496)
Co-authored-by: Yevhen Shevchenko <yevhen@signoz.io>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-03-24 17:09:31 +05:30
GitStart
1e7280136a fix: view traces button (#2458) 2023-03-24 15:08:35 +05:30
Srikanth Chekuri
17a5bc8cc3 feat: metrics query range v3 (#2265) 2023-03-23 19:45:15 +05:30
Chintan Sudani
c3763032df feat: added submenu system at sidebar (#2486)
* fix: Removed Strict mode to stop render twice

* feat: added submenu system at sidebar
2023-03-23 14:50:17 +05:30
GitStart
da4cbf6c2f fix: tabs deprecation warning from antd (#2479)
Co-authored-by: gitstart <gitstart@users.noreply.github.com>
Co-authored-by: Chintan Sudani <46838508+techchintan@users.noreply.github.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-03-22 12:01:37 +05:30
GitStart
97bfee48e1 fix: slider deprecation warning from antd (#2478)
Co-authored-by: gitstart <gitstart@users.noreply.github.com>
Co-authored-by: Chintan Sudani <46838508+techchintan@users.noreply.github.com>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-03-22 11:33:36 +05:30
Ankit Anand
da23d9e087 Update README.md (#2480)
Added pic for exceptions monitoring, added shadow on app metrics image.

Co-authored-by: Pranay Prateek <pranay@signoz.io>
2023-03-22 10:23:21 +05:30
Nityananda Gohain
27db1b9080 Merge pull request #2456 from SigNoz/feat/opamp-logparing
feat: logs parsing pipeline support in opamp
2023-03-22 09:55:53 +05:30
Nityananda Gohain
55d7285c9a Merge branch 'develop' into feat/opamp-logparing 2023-03-22 09:47:03 +05:30
Vishal Sharma
27c48674d4 fix: update query range params (#2453) 2023-03-21 22:53:56 +05:30
Ankit Anand
d29dfa0751 Update README.md (#2475)
Updated product screenshots, bullet points for features
2023-03-21 16:21:49 +05:30
Srikanth Chekuri
d951483597 fix: substitute nan negative rate from couter resets (#2449) 2023-03-21 11:47:04 +05:30
Chintan Sudani
481792d4ca fix: create/edit panel shows a blank page (#2473) 2023-03-20 18:46:20 +05:30
Vishal Sharma
0fa20445d8 Merge branch 'develop' into feat/opamp-logparing 2023-03-20 17:40:09 +05:30
nityanandagohain
eb4ac18162 feat: processor builder updated with new logic and tests 2023-03-17 17:39:28 +05:30
Palash Gupta
1ddda19c8e feat: table view is updated for body field (#2465) 2023-03-17 15:21:02 +05:30
Palash Gupta
91c3abae37 feat: editor is updated (#2464) 2023-03-17 15:12:31 +05:30
nityanandagohain
b5debe6ea2 Merge remote-tracking branch 'upstream/feat/opamp-logparing' into feat/opamp-logparing 2023-03-16 16:39:11 +05:30
nityanandagohain
7367f8dd4b fix: tests fixed 2023-03-16 10:24:20 +05:30
nityanandagohain
bac717e9e6 fix: use structs instead of interface 2023-03-16 10:24:08 +05:30
nityanandagohain
e1219ea942 fix: use structs instead of interface 2023-03-16 10:20:57 +05:30
nityanandagohain
1c867d3b4c Merge remote-tracking branch 'upstream/develop' into feat/opamp-logparing 2023-03-15 20:36:01 +05:30
Nityananda Gohain
65c2a0bf6a Merge pull request #2455 from SigNoz/feat/last10versions
fix: get last n versions in getConfigHistory
2023-03-15 20:27:07 +05:30
nityanandagohain
755d64061e fix: minor spelling fixes 2023-03-15 17:55:02 +05:30
nityanandagohain
500ab02c47 chore: logs parsing pipeline support in opamp 2023-03-15 17:42:24 +05:30
nityanandagohain
dfef41913f fix: get last 10 versions in getConfigHistory 2023-03-15 16:26:46 +05:30
Srikanth Chekuri
210c5fd7f2 feat: opamp server application (#1787)
* feat: opamp server application

* chore: opamp

* chore: refactor server implementation

* chore: add Stop

* chore: merged opamp updates

* chore: removed all errorf

* chore: added a comment about zero version

* feat: added user context for created by

* chore: changed debugf to debug

* chore: removed lb from opamp + added config parser

* fix: added userid to ConfigNewVersion()

* chore: removed user id from contxt and added config parser

* fix: removed lock inside re-deploy

* chore: added config db fix

* fix: merged app/server.go from develop

* fix: restored extract jwt

* Update pkg/query-service/app/server.go

Co-authored-by: Nityananda Gohain <nityanandagohain@gmail.com>

* fix: dependency version fix and import added

---------

Co-authored-by: Pranay Prateek <pranay@signoz.io>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
Co-authored-by: mindhash <mindhash@mindhashs-MacBook-Pro.local>
Co-authored-by: Nityananda Gohain <nityanandagohain@gmail.com>
2023-03-15 15:09:15 +05:30
Rajat Dwivedi
c4b052c51e upgraded some deprecated packages (#2424)
* fix: upgrade deprecated pkg

* fix: reverted linebreak rules

* chore: some of the refactoring is done regarding the performance

---------

Co-authored-by: Chintan Sudani <46838508+techchintan@users.noreply.github.com>
Co-authored-by: palashgdev <palashgdev@gmail.com>
2023-03-14 16:55:15 +05:30
Ankit Nayan
da79f93495 Merge pull request #2442 from SigNoz/release/v0.17.0
Release/v0.17.0
2023-03-11 19:51:41 +05:30
Srikanth Chekuri
83e3e3c3ed Merge branch 'develop' into release/v0.17.0 2023-03-11 16:47:38 +05:30
Srikanth Chekuri
7508c9148f fix: address legend formatting for external call error % (#2443) 2023-03-11 16:44:58 +05:30
Srikanth Chekuri
b15463fd38 chore: pin versions - SigNoz 0.17.0, SigNoz OtelCollector 0.66.6 2023-03-10 21:52:42 +05:30
palashgdev
66b2e17bba feat: color coding is added in the table view (#2437) 2023-03-10 13:55:42 +05:30
Srikanth Chekuri
9af991e424 feat: add attrs filters autocomplete endpoints (#2264) 2023-03-10 11:22:34 +05:30
Maciej Wakuła
59497ed53c Pop!OS support (same as ubuntu) #2417 (#2420) 2023-03-10 03:49:02 +05:30
palashgdev
7f04a4407b feat: color coding is added in the list view (#2432) 2023-03-07 18:15:54 +05:30
palashgdev
2a03291171 feat: body is added in the log (#2431) 2023-03-07 18:07:23 +05:30
palashgdev
53bfc33075 chore: panel Type is disabled for now (#2434) 2023-03-07 17:49:18 +05:30
GitStart
c821e8bb75 feat: add ability to change panel type (#2383)
* feat: add ability to change panel type

* feat: add ability to change panel type

---------

Co-authored-by: gitstart <gitstart@users.noreply.github.com>
Co-authored-by: palashgdev <palashgdev@gmail.com>
2023-03-07 16:55:59 +05:30
GitStart
eff87f2666 feat: move form into useForm from antd (#2403)
Co-authored-by: gitstart <gitstart@users.noreply.github.com>
Co-authored-by: palashgdev <palashgdev@gmail.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-03-07 14:56:56 +05:30
Srikanth Chekuri
3f5171dc69 chore: bump SigNoz/prometheus (#2094) 2023-03-07 13:37:31 +05:30
Srikanth Chekuri
c5d7d9d134 feat: ability to save and retrieve the explorer queries (#2284) 2023-03-07 00:26:25 +05:30
Srikanth Chekuri
6defa0ac8b feat: metric attribute autocomplete for the aggregation type (#2263) 2023-03-04 00:05:16 +05:30
Srikanth Chekuri
e3fee332c7 chore: update CODEOWNERS for */query-service/ (#2421) 2023-03-03 23:45:04 +05:30
Srikanth Chekuri
2c7cefcc74 fix: add the missing /health route removed in #2261 (#2419) 2023-03-03 18:07:24 +05:30
GitStart
080a53a9b4 fix: menu antd deprecation warning (#2416)
* fix: menu antd deprecation warning

* chore: some of the refactoring is updated

---------

Co-authored-by: gitstart <gitstart@users.noreply.github.com>
Co-authored-by: palashgdev <palashgdev@gmail.com>
2023-03-03 16:39:24 +05:30
Vishal Sharma
2a5cb78964 feat: add span links support (#2415)
* feat: add span links support

* fix: handle an edge case

* chore: test is fixed

* chore: some of the refactoring is updated

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-03-03 14:35:11 +05:30
Ankit Nayan
b99d7009a1 Merge pull request #2261 from ahsanbarkati/ahsan/pat
feat(PAT): Add personal access token for programmatic access
2023-03-02 11:01:14 +05:30
palashgdev
e46b7e41e5 feat: restricted_SELECTED_FIELDS is filtered from the selected list (#2401)
* feat: restricted_SELECTED_FIELDS is filtered from the selected list

* chore: selected id fields is removed from the rendering part
2023-03-01 17:26:37 +05:30
palashgdev
50270281e3 fix: Logs Live Tail is fixed (#2380)
* logs is updated

* fix: log live tail is updated

* fix: live tail is fixed

* chore: build is fixed

* chore: useEffect is removed

* chore: getLogsAggregate callback is added in the useEffect
2023-03-01 17:18:02 +05:30
Srikanth Chekuri
5e5e81d81d chore: add payload types for autocomplete requests (#2244) 2023-03-01 10:55:07 +05:30
Ahsan Barkati
eb2fe20025 Address review comments 2023-03-01 00:11:44 +05:30
Ahsan Barkati
df7f276f03 Change header name 2023-03-01 00:11:44 +05:30
Ahsan Barkati
b0f62daa24 Cleanup rbac.go 2023-03-01 00:11:44 +05:30
Ahsan Barkati
797352583a Create PAT supporting auth middleware 2023-03-01 00:11:44 +05:30
Ahsan Barkati
96267e2e3a Add GetPAT function 2023-03-01 00:06:33 +05:30
Ahsan Barkati
388ef9453c Add APIs for PAT 2023-03-01 00:06:33 +05:30
Prashant Shahi
995e45713c chore: health endpoint related changes (#2275) 2023-02-28 23:42:21 +05:30
Mary Ojo
b0d5b15330 style: corrected the positioning of the charts tooltip (#2402)
* style: corrected the positioning of the charts tooltip

* style: stored value for pixel in variable

* chore: logic is shifted to plugin

---------

Co-authored-by: palashgdev <palashgdev@gmail.com>
2023-02-28 14:16:31 +05:30
palashgdev
80cd317b3b feat: color encoding is added in the logs raw view (#2398)
* chore: some of the changes are updated

* feat: ansi-to-html is added

* feat: color is added in the raw view
2023-02-28 11:03:02 +05:30
Ankit Nayan
51721f97c7 Merge pull request #2379 from SigNoz/release/v0.16.2
Release/v0.16.2
2023-02-24 19:31:06 +05:30
801 changed files with 45126 additions and 7315 deletions

10
.github/CODEOWNERS vendored
View File

@@ -2,6 +2,12 @@
# Owners are automatically requested for review for PRs that changes code
# that they own.
* @ankitnayan
/frontend/ @palashgdev @pranshuchittora
/frontend/ @palashgdev
/deploy/ @prashant-shahi
/pkg/query-service/ @srikanthccv
/sample-apps/ @prashant-shahi
**/query-service/ @srikanthccv
Makefile @srikanthccv
go.* @srikanthccv
.git* @srikanthccv
.github @prashant-shahi

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install dependencies
run: cd frontend && yarn install
- name: Run ESLint
@@ -31,7 +31,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Run tests
shell: bash
run: |
@@ -45,7 +45,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Build EE query-service image
shell: bash
run: |

View File

@@ -39,11 +39,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -54,7 +54,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -68,4 +68,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2

View File

@@ -7,12 +7,7 @@ jobs:
lint-commits:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.1
- uses: actions/checkout@v3
with:
# we actually need "github.event.pull_request.commits + 1" commit
fetch-depth: 0
- uses: actions/setup-node@v2.1.0
# or just "yarn" if you depend on "@commitlint/cli" already
- run: yarn add @commitlint/cli
- run: yarn add @commitlint/config-conventional
- run: yarn run commitlint --config ./node_modules/@commitlint/config-conventional/index.js --from HEAD~${{ github.event.pull_request.commits }} --to HEAD
- uses: wagoid/commitlint-github-action@v5

View File

@@ -12,11 +12,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Codebase
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: signoz/gh-bot
- name: Use Node v16
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: 16
- name: Setup Cache & Install Dependencies

View File

@@ -13,7 +13,7 @@ jobs:
DOCKER_TAG: pull-${{ github.event.number }}
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Build query-service image
env:
@@ -69,12 +69,14 @@ jobs:
--restart='OnFailure' -i --rm --command -- curl -X POST -F \
'locust_count=6' -F 'hatch_rate=2' http://locust-master:8089/swarm
- name: Get short commit SHA and display tunnel URL
- name: Get short commit SHA, display tunnel URL and IP Address of the worker node
id: get-subdomain
run: |
subdomain="pr-$(git rev-parse --short HEAD)"
echo "URL for tunnelling: https://$subdomain.loca.lt"
echo "::set-output name=subdomain::$subdomain"
echo "subdomain=$subdomain" >> $GITHUB_OUTPUT
worker_ip="$(curl -4 -s ipconfig.io/ip)"
echo "Worker node IP address: $worker_ip"
- name: Start tunnel
env:

View File

@@ -9,8 +9,8 @@ jobs:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: "16.x"
- name: Install dependencies

View File

@@ -5,7 +5,7 @@ name: VerifyIssue
on:
pull_request:
types: [edited, synchronize, opened, reopened]
types: [edited, opened]
check_run:
jobs:
@@ -14,6 +14,6 @@ jobs:
name: Ensure Pull Request has a linked issue.
steps:
- name: Verify Linked Issue
uses: hattan/verify-linked-issue-action@v1.1.0
uses: srikanthccv/verify-linked-issue-action@v0.71
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -14,19 +14,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
with:
version: latest
- name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: benjlevesque/short-sha@v1.2
- uses: benjlevesque/short-sha@v2.2
id: short-sha
- name: Get branch name
id: branch-name
@@ -49,19 +49,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
with:
version: latest
- name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: benjlevesque/short-sha@v1.2
- uses: benjlevesque/short-sha@v2.2
id: short-sha
- name: Get branch name
id: branch-name
@@ -84,7 +84,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install dependencies
working-directory: frontend
run: yarn install
@@ -97,15 +97,15 @@ jobs:
run: npm run lint
continue-on-error: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
with:
version: latest
- name: Login to DockerHub
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: benjlevesque/short-sha@v1.2
- uses: benjlevesque/short-sha@v2.2
id: short-sha
- name: Get branch name
id: branch-name

View File

@@ -12,6 +12,12 @@ on:
jobs:
update_release_draft:
permissions:
# write permission is required to create a github release
contents: write
# write permission is required for autolabeler
# otherwise, read permission is required at least
pull-requests: write
runs-on: ubuntu-latest
steps:
# (Optional) GitHub Enterprise requires GHE_HOST variable set

View File

@@ -8,9 +8,15 @@ jobs:
remove:
runs-on: ubuntu-latest
steps:
- name: Remove label
uses: buildsville/add-remove-label@v1
- name: Remove label ok-to-test from PR
uses: buildsville/add-remove-label@v2.0.0
with:
label: ok-to-test,testing-deploy
label: ok-to-test
type: remove
token: ${{ secrets.GITHUB_TOKEN }}
- name: Remove label testing-deploy from PR
uses: buildsville/add-remove-label@v2.0.0
with:
label: testing-deploy
type: remove
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -3,7 +3,7 @@ on:
pull_request:
branches:
- main
- v*
- develop
paths:
- 'frontend/**'
defaults:
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Sonar analysis

View File

@@ -11,21 +11,23 @@ jobs:
environment: staging
steps:
- name: Executing remote ssh commands using ssh key
uses: appleboy/ssh-action@v0.1.6
uses: appleboy/ssh-action@v0.1.8
env:
GITHUB_BRANCH: develop
GITHUB_SHA: ${{ github.sha }}
with:
host: ${{ secrets.HOST_DNS }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
key: ${{ secrets.SSH_KEY }}
envs: GITHUB_BRANCH,GITHUB_SHA
command_timeout: 60m
script: |
echo "GITHUB_BRANCH: ${GITHUB_BRANCH}"
echo "GITHUB_SHA: ${GITHUB_SHA}"
export DOCKER_TAG="${GITHUB_SHA:0:7}" # needed for child process to access it
export OTELCOL_TAG="main"
docker system prune --force
docker pull signoz/signoz-otel-collector:main
cd ~/signoz
git status
git add .

View File

@@ -11,14 +11,14 @@ jobs:
if: ${{ github.event.label.name == 'testing-deploy' }}
steps:
- name: Executing remote ssh commands using ssh key
uses: appleboy/ssh-action@v0.1.6
uses: appleboy/ssh-action@v0.1.8
env:
GITHUB_BRANCH: ${{ github.head_ref || github.ref_name }}
GITHUB_SHA: ${{ github.sha }}
with:
host: ${{ secrets.HOST_DNS }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
key: ${{ secrets.SSH_KEY }}
envs: GITHUB_BRANCH,GITHUB_SHA
command_timeout: 60m
script: |

6
.gitignore vendored
View File

@@ -1,7 +1,5 @@
node_modules
yarn.lock
package.json
deploy/docker/environment_tiny/common_test
frontend/node_modules
@@ -52,4 +50,6 @@ ee/query-service/tests/test-deploy/data/
*.db
/deploy/docker/clickhouse-setup/data/
/deploy/docker-swarm/clickhouse-setup/data/
bin/
bin/
*/query-service/queries.active

View File

@@ -80,7 +80,7 @@ Before sending us a pull request, please ensure that,
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
**Note:** Unless your change is small, **please** consider submitting different Pull Rrequest(s):
**Note:** Unless your change is small, **please** consider submitting different Pull Request(s):
* 1⃣ First PR should include the overall structure of the new component:
* Readme, configuration, interfaces or base classes, etc...

View File

@@ -54,7 +54,7 @@ build-push-frontend:
@echo "--> Building and pushing frontend docker image"
@echo "------------------"
@cd $(FRONTEND_DIRECTORY) && \
docker buildx build --file Dockerfile --progress plane --push --platform linux/arm64,linux/amd64 \
docker buildx build --file Dockerfile --progress plain --push --platform linux/arm64,linux/amd64 \
--tag $(REPONAME)/$(FRONTEND_DOCKER_IMAGE):$(DOCKER_TAG) .
# Steps to build and push docker image of query service
@@ -73,7 +73,7 @@ build-push-query-service:
@echo "------------------"
@echo "--> Building and pushing query-service docker image"
@echo "------------------"
@docker buildx build --file $(QUERY_SERVICE_DIRECTORY)/Dockerfile --progress plane \
@docker buildx build --file $(QUERY_SERVICE_DIRECTORY)/Dockerfile --progress plain \
--push --platform linux/arm64,linux/amd64 --build-arg LD_FLAGS="$(LD_FLAGS)" \
--tag $(REPONAME)/$(QUERY_SERVICE_DOCKER_IMAGE):$(DOCKER_TAG) .
@@ -98,7 +98,7 @@ build-push-ee-query-service:
@echo "--> Building and pushing query-service docker image"
@echo "------------------"
@docker buildx build --file $(EE_QUERY_SERVICE_DIRECTORY)/Dockerfile \
--progress plane --push --platform linux/arm64,linux/amd64 \
--progress plain --push --platform linux/arm64,linux/amd64 \
--build-arg LD_FLAGS="$(LD_FLAGS)" --tag $(REPONAME)/$(QUERY_SERVICE_DOCKER_IMAGE):$(DOCKER_TAG) .
dev-setup:
@@ -136,5 +136,18 @@ clear-swarm-data:
@docker run --rm -v "$(PWD)/$(SWARM_DIRECTORY)/data:/pwd" busybox \
sh -c "cd /pwd && rm -rf alertmanager/* clickhouse*/* signoz/* zookeeper-*/*"
clear-standalone-ch:
@docker run --rm -v "$(PWD)/$(STANDALONE_DIRECTORY)/data:/pwd" busybox \
sh -c "cd /pwd && rm -rf clickhouse*/* zookeeper-*/*"
clear-swarm-ch:
@docker run --rm -v "$(PWD)/$(SWARM_DIRECTORY)/data:/pwd" busybox \
sh -c "cd /pwd && rm -rf clickhouse*/* zookeeper-*/*"
test:
go test ./pkg/query-service/app/metrics/...
go test ./pkg/query-service/cache/...
go test ./pkg/query-service/app/...
go test ./pkg/query-service/app/querier/...
go test ./pkg/query-service/converter/...
go test ./pkg/query-service/formatter/...

View File

@@ -85,9 +85,9 @@ Hier findest du die vollständige Liste von unterstützten Programmiersprachen -
### Bereitstellung mit Docker
Bitte folge den [hier](https://signoz.io/docs/deployment/docker/) aufgelisteten Schritten um deine Anwendung mit Docker bereitzustellen.
Bitte folge den [hier](https://signoz.io/docs/install/docker/) aufgelisteten Schritten um deine Anwendung mit Docker bereitzustellen.
Die [Anleitungen zur Fehlerbehebung](https://signoz.io/docs/deployment/troubleshooting) könnten hilfreich sein, falls du auf irgendwelche Schwierigkeiten stößt.
Die [Anleitungen zur Fehlerbehebung](https://signoz.io/docs/install/troubleshooting/) könnten hilfreich sein, falls du auf irgendwelche Schwierigkeiten stößt.
<p>&nbsp </p>

View File

@@ -35,19 +35,41 @@ SigNoz helps developers monitor applications and troubleshoot problems in their
👉 Filter and query logs, build dashboards and alerts based on attributes in logs
![screenzy-1670570187181](https://user-images.githubusercontent.com/504541/206646629-829fdafe-70e2-4503-a9c4-1301b7918586.png)
<br />
![screenzy-1670570193901](https://user-images.githubusercontent.com/504541/206646676-a676fdeb-331c-4847-aea9-d1cabf7c47e1.png)
<br />
![screenzy-1670570199026](https://user-images.githubusercontent.com/504541/206646754-28c5534f-0377-428c-9c6e-5c7c0d9dd22d.png)
<br />
![screenzy-1670569888865](https://user-images.githubusercontent.com/504541/206645819-1e865a56-71b4-4fde-80cc-fbdb137a4da5.png)
👉 Record exceptions automatically in Python, Java, Ruby, and Javascript
👉 Easy to set alerts with DIY query builder
### Application Metrics
![application_metrics](https://user-images.githubusercontent.com/83692067/226637410-900dbc5e-6705-4b11-a10c-bd0faeb2a92f.png)
### Distributed Tracing
<img width="2068" alt="distributed_tracing_2 2" src="https://user-images.githubusercontent.com/83692067/226536447-bae58321-6a22-4ed3-af80-e3e964cb3489.png">
<img width="2068" alt="distributed_tracing_1" src="https://user-images.githubusercontent.com/83692067/226536462-939745b6-4f9d-45a6-8016-814837e7f7b4.png">
### Logs Management
<img width="2068" alt="logs_management" src="https://user-images.githubusercontent.com/83692067/226536482-b8a5c4af-b69c-43d5-969c-338bd5eaf1a5.png">
### Infrastructure Monitoring
<img width="2068" alt="infrastructure_monitoring" src="https://user-images.githubusercontent.com/83692067/226536496-f38c4dbf-e03c-4158-8be0-32d4a61158c7.png">
### Exceptions Monitoring
![exceptions_light](https://user-images.githubusercontent.com/83692067/226637967-4188d024-3ac9-4799-be95-f5ea9c45436f.png)
### Alerts
<img width="2068" alt="alerts_management" src="https://user-images.githubusercontent.com/83692067/226536548-2c81e2e8-c12d-47e8-bad7-c6be79055def.png">
<br /><br />
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/Contributing.svg" width="50px" />
## Join our Slack community
@@ -55,7 +77,6 @@ Come say Hi to us on [Slack](https://signoz.io/slack) 👋
<br /><br />
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/Features.svg" width="50px" />
## Features:
@@ -65,10 +86,13 @@ Come say Hi to us on [Slack](https://signoz.io/slack) 👋
- See exact request trace to figure out issues in downstream services, slow DB queries, call to 3rd party services like payment gateways, etc
- Filter traces by service name, operation, latency, error, tags/annotations.
- Run aggregates on trace data (events/spans) to get business relevant metrics. e.g. You can get error rate and 99th percentile latency of `customer_type: gold` or `deployment_version: v2` or `external_call: paypal`
- Native support for OpenTelemetry Logs, advanced log query builder, and automatic log collection from k8s cluster
- Lightning quick log analytics ([Logs Perf. Benchmark](https://signoz.io/blog/logs-performance-benchmark/))
- End-to-End visibility into infrastructure performance, ingest metrics from all kinds of host environments
- Easy to set alerts with DIY query builder
<br /><br />
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/WhatsCool.svg" width="50px" />
## Why SigNoz?
@@ -97,15 +121,14 @@ You can find the complete list of languages here - https://opentelemetry.io/docs
<br /><br />
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/Philosophy.svg" width="50px" />
## Getting Started
### Deploy using Docker
Please follow the steps listed [here](https://signoz.io/docs/deployment/docker/) to install using docker
Please follow the steps listed [here](https://signoz.io/docs/install/docker/) to install using docker
The [troubleshooting instructions](https://signoz.io/docs/deployment/troubleshooting) may be helpful if you face any issues.
The [troubleshooting instructions](https://signoz.io/docs/install/troubleshooting/) may be helpful if you face any issues.
<p>&nbsp </p>
@@ -116,7 +139,6 @@ Please follow the steps listed [here](https://signoz.io/docs/deployment/helm_cha
<br /><br />
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/UseSigNoz.svg" width="50px" />
## Comparisons to Familiar Tools
@@ -158,7 +180,6 @@ We have published benchmarks comparing Loki with SigNoz. Check it out [here](htt
<br /><br />
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/Contributors.svg" width="50px" />
## Contributing
@@ -185,7 +206,6 @@ Not sure how to get started? Just ping us on `#contributing` in our [slack commu
<br /><br />
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/DevelopingLocally.svg" width="50px" />
## Documentation
@@ -193,7 +213,6 @@ You can find docs at https://signoz.io/docs/. If you need any clarification or f
<br /><br />
<img align="left" src="https://signoz-public.s3.us-east-2.amazonaws.com/Contributing.svg" width="50px" />
## Community

View File

@@ -84,9 +84,9 @@ Você pode encontrar a lista completa de linguagens aqui - https://opentelemetry
### Implantar usando Docker
Siga as etapas listadas [aqui](https://signoz.io/docs/deployment/docker/) para instalar usando o Docker.
Siga as etapas listadas [aqui](https://signoz.io/docs/install/docker/) para instalar usando o Docker.
Esse [guia para solução de problemas](https://signoz.io/docs/deployment/troubleshooting) pode ser útil se você enfrentar quaisquer problemas.
Esse [guia para solução de problemas](https://signoz.io/docs/install/troubleshooting/) pode ser útil se você enfrentar quaisquer problemas.
<p>&nbsp </p>

View File

@@ -80,9 +80,9 @@ SigNoz帮助开发人员监控应用并排查已部署应用中的问题。SigNo
### 使用Docker部署
请按照[这里](https://signoz.io/docs/deployment/docker/)列出的步骤使用Docker来安装
请按照[这里](https://signoz.io/docs/install/docker/)列出的步骤使用Docker来安装
如果你遇到任何问题,这个[排查指南](https://signoz.io/docs/deployment/troubleshooting)会对你有帮助。
如果你遇到任何问题,这个[排查指南](https://signoz.io/docs/install/troubleshooting/)会对你有帮助。
<p>&nbsp </p>

View File

@@ -7,9 +7,21 @@
</default>
<s3>
<type>s3</type>
<endpoint>https://BUCKET-NAME.s3.amazonaws.com/data/</endpoint>
<!-- For S3 cold storage,
if region is us-east-1, endpoint can be https://<bucket-name>.s3.amazonaws.com
if region is not us-east-1, endpoint should be https://<bucket-name>.s3-<region>.amazonaws.com
For GCS cold storage,
endpoint should be https://storage.googleapis.com/<bucket-name>/data/
-->
<endpoint>https://BUCKET-NAME.s3-REGION-NAME.amazonaws.com/data/</endpoint>
<access_key_id>ACCESS-KEY-ID</access_key_id>
<secret_access_key>SECRET-ACCESS-KEY</secret_access_key>
<!-- In case of S3, uncomment the below configuration in case you want to read
AWS credentials from the Environment variables if they exist. -->
<!-- <use_environment_credentials>true</use_environment_credentials> -->
<!-- In case of GCS, uncomment the below configuration, since GCS does
not support batch deletion and result in error messages in logs. -->
<!-- <support_batch_delete>false</support_batch_delete> -->
</s3>
</disks>
<policies>

View File

@@ -34,7 +34,7 @@ x-clickhouse-depend: &clickhouse-depend
services:
zookeeper-1:
image: bitnami/zookeeper:3.7.0
image: bitnami/zookeeper:3.7.1
hostname: zookeeper-1
user: root
ports:
@@ -124,7 +124,7 @@ services:
# - ./data/clickhouse-3/:/var/lib/clickhouse/
alertmanager:
image: signoz/alertmanager:0.23.0-0.2
image: signoz/alertmanager:0.23.1
volumes:
- ./data/alertmanager:/data
command:
@@ -137,7 +137,7 @@ services:
condition: on-failure
query-service:
image: signoz/query-service:0.16.2
image: signoz/query-service:0.22.0
command: ["-config=/root/config/prometheus.yml"]
# ports:
# - "6060:6060" # pprof port
@@ -156,7 +156,7 @@ services:
- TELEMETRY_ENABLED=true
- DEPLOYMENT_TYPE=docker-swarm
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "localhost:8080/api/v1/version"]
test: ["CMD", "wget", "--spider", "-q", "localhost:8080/api/v1/health"]
interval: 30s
timeout: 5s
retries: 3
@@ -166,7 +166,7 @@ services:
<<: *clickhouse-depend
frontend:
image: signoz/frontend:0.16.2
image: signoz/frontend:0.22.0
deploy:
restart_policy:
condition: on-failure
@@ -179,8 +179,8 @@ services:
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
otel-collector:
image: signoz/signoz-otel-collector:0.66.5
command: ["--config=/etc/otel-collector-config.yaml"]
image: signoz/signoz-otel-collector:0.79.1
command: ["--config=/etc/otel-collector-config.yaml", "--feature-gates=-pkg.translator.prometheus.NormalizeName"]
user: root # required for reading docker container logs
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
@@ -208,8 +208,8 @@ services:
<<: *clickhouse-depend
otel-collector-metrics:
image: signoz/signoz-otel-collector:0.66.5
command: ["--config=/etc/otel-collector-metrics-config.yaml"]
image: signoz/signoz-otel-collector:0.79.1
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:
@@ -233,7 +233,7 @@ services:
max-file: "3"
load-hotrod:
image: "grubykarol/locust:1.2.3-python3.9-alpine3.12"
image: "signoz/locust:1.2.3"
hostname: load-hotrod
environment:
ATTACKED_HOST: http://hotrod:8080

View File

@@ -75,7 +75,7 @@ processors:
timeout: 10s
resourcedetection:
# Using OTEL_RESOURCE_ATTRIBUTES envvar, env detector adds custom labels.
detectors: [env, system] # include ec2 for AWS, gce for GCP and azure for Azure.
detectors: [env, system] # include ec2 for AWS, gcp for GCP and azure for Azure.
timeout: 2s
signozspanmetrics/prometheus:
metrics_exporter: prometheus

View File

@@ -7,9 +7,21 @@
</default>
<s3>
<type>s3</type>
<endpoint>https://BUCKET-NAME.s3.amazonaws.com/data/</endpoint>
<!-- For S3 cold storage,
if region is us-east-1, endpoint can be https://<bucket-name>.s3.amazonaws.com
if region is not us-east-1, endpoint should be https://<bucket-name>.s3-<region>.amazonaws.com
For GCS cold storage,
endpoint should be https://storage.googleapis.com/<bucket-name>/data/
-->
<endpoint>https://BUCKET-NAME.s3-REGION-NAME.amazonaws.com/data/</endpoint>
<access_key_id>ACCESS-KEY-ID</access_key_id>
<secret_access_key>SECRET-ACCESS-KEY</secret_access_key>
<!-- In case of S3, uncomment the below configuration in case you want to read
AWS credentials from the Environment variables if they exist. -->
<!-- <use_environment_credentials>true</use_environment_credentials> -->
<!-- In case of GCS, uncomment the below configuration, since GCS does
not support batch deletion and result in error messages in logs. -->
<!-- <support_batch_delete>false</support_batch_delete> -->
</s3>
</disks>
<policies>

View File

@@ -27,7 +27,7 @@ services:
alertmanager:
container_name: alertmanager
image: signoz/alertmanager:0.23.0-0.2
image: signoz/alertmanager:0.23.1
volumes:
- ./data/alertmanager:/data
depends_on:
@@ -41,8 +41,8 @@ services:
# Notes for Maintainers/Contributors who will change Line Numbers of Frontend & Query-Section. Please Update Line Numbers in `./scripts/commentLinesForSetup.sh` & `./CONTRIBUTING.md`
otel-collector:
container_name: otel-collector
image: signoz/signoz-otel-collector:0.66.5
command: ["--config=/etc/otel-collector-config.yaml"]
image: signoz/signoz-otel-collector:0.79.1
command: ["--config=/etc/otel-collector-config.yaml", "--feature-gates=-pkg.translator.prometheus.NormalizeName"]
# user: root # required for reading docker container logs
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
@@ -67,8 +67,8 @@ services:
otel-collector-metrics:
container_name: otel-collector-metrics
image: signoz/signoz-otel-collector:0.66.5
command: ["--config=/etc/otel-collector-metrics-config.yaml"]
image: signoz/signoz-otel-collector:0.79.1
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:
@@ -93,7 +93,7 @@ services:
- JAEGER_ENDPOINT=http://otel-collector:14268/api/traces
load-hotrod:
image: "grubykarol/locust:1.2.3-python3.9-alpine3.12"
image: "signoz/locust:1.2.3"
container_name: load-hotrod
hostname: load-hotrod
environment:

View File

@@ -28,7 +28,7 @@ services:
- "8080:8080"
restart: on-failure
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "localhost:8080/api/v1/version"]
test: ["CMD", "wget", "--spider", "-q", "localhost:8080/api/v1/health"]
interval: 30s
timeout: 5s
retries: 3

View File

@@ -34,9 +34,9 @@ x-clickhouse-depend: &clickhouse-depend
# condition: service_healthy
services:
zookeeper-1:
image: bitnami/zookeeper:3.7.0
image: bitnami/zookeeper:3.7.1
container_name: zookeeper-1
hostname: zookeeper-1
user: root
@@ -120,7 +120,7 @@ services:
# - ./data/clickhouse-2/:/var/lib/clickhouse/
# - ./user_scripts:/var/lib/clickhouse/user_scripts/
# clickhouse-3:
# <<: *clickhouse-defaults
# container_name: clickhouse-3
@@ -139,7 +139,7 @@ services:
# - ./user_scripts:/var/lib/clickhouse/user_scripts/
alertmanager:
image: signoz/alertmanager:${ALERTMANAGER_TAG:-0.23.0-0.2}
image: signoz/alertmanager:${ALERTMANAGER_TAG:-0.23.1}
volumes:
- ./data/alertmanager:/data
depends_on:
@@ -150,10 +150,10 @@ services:
- --queryService.url=http://query-service:8085
- --storage.path=/data
# 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:
image: signoz/query-service:${DOCKER_TAG:-0.16.2}
image: signoz/query-service:${DOCKER_TAG:-0.22.0}
container_name: query-service
command: ["-config=/root/config/prometheus.yml"]
# ports:
@@ -174,14 +174,14 @@ services:
- DEPLOYMENT_TYPE=docker-standalone-amd
restart: on-failure
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "localhost:8080/api/v1/version"]
test: ["CMD", "wget", "--spider", "-q", "localhost:8080/api/v1/health"]
interval: 30s
timeout: 5s
retries: 3
<<: *clickhouse-depend
frontend:
image: signoz/frontend:${DOCKER_TAG:-0.16.2}
image: signoz/frontend:${DOCKER_TAG:-0.22.0}
container_name: frontend
restart: on-failure
depends_on:
@@ -193,8 +193,8 @@ services:
- ../common/nginx-config.conf:/etc/nginx/conf.d/default.conf
otel-collector:
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.66.5}
command: ["--config=/etc/otel-collector-config.yaml"]
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.79.1}
command: ["--config=/etc/otel-collector-config.yaml", "--feature-gates=-pkg.translator.prometheus.NormalizeName"]
user: root # required for reading docker container logs
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
@@ -219,8 +219,8 @@ services:
<<: *clickhouse-depend
otel-collector-metrics:
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.66.5}
command: ["--config=/etc/otel-collector-metrics-config.yaml"]
image: signoz/signoz-otel-collector:${OTELCOL_TAG:-0.79.1}
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:
@@ -243,7 +243,7 @@ services:
- JAEGER_ENDPOINT=http://otel-collector:14268/api/traces
load-hotrod:
image: "grubykarol/locust:1.2.3-python3.9-alpine3.12"
image: "signoz/locust:1.2.3"
container_name: load-hotrod
hostname: load-hotrod
environment:

View File

@@ -70,6 +70,40 @@ receivers:
processors:
logstransform/internal:
operators:
- type: trace_parser
if: '"trace_id" in attributes or "span_id" in attributes'
trace_id:
parse_from: attributes.trace_id
span_id:
parse_from: attributes.span_id
output: remove_trace_id
- type: trace_parser
if: '"traceId" in attributes or "spanId" in attributes'
trace_id:
parse_from: attributes.traceId
span_id:
parse_from: attributes.spanId
output: remove_traceId
- id: remove_traceId
type: remove
if: '"traceId" in attributes'
field: attributes.traceId
output: remove_spanId
- id: remove_spanId
type: remove
if: '"spanId" in attributes'
field: attributes.spanId
- id: remove_trace_id
type: remove
if: '"trace_id" in attributes'
field: attributes.trace_id
output: remove_span_id
- id: remove_span_id
type: remove
if: '"span_id" in attributes'
field: attributes.span_id
batch:
send_batch_size: 10000
send_batch_max_size: 11000
@@ -104,7 +138,7 @@ processors:
# retry_on_failure: true
resourcedetection:
# Using OTEL_RESOURCE_ATTRIBUTES envvar, env detector adds custom labels.
detectors: [env, system] # include ec2 for AWS, gce for GCP and azure for Azure.
detectors: [env, system] # include ec2 for AWS, gcp for GCP and azure for Azure.
timeout: 2s
extensions:
@@ -172,5 +206,5 @@ service:
exporters: [prometheus]
logs:
receivers: [otlp, filelog/dockercontainers]
processors: [batch]
processors: [logstransform/internal, batch]
exporters: [clickhouselogsexporter]

View File

@@ -51,7 +51,7 @@ check_os() {
os_name="$(cat /etc/*-release | awk -F= '$1 == "NAME" { gsub(/"/, ""); print $2; exit }')"
case "$os_name" in
Ubuntu*)
Ubuntu*|Pop!_OS)
desired_os=1
os="ubuntu"
package_manager="apt-get"
@@ -125,7 +125,7 @@ check_ports_occupied() {
echo "+++++++++++ ERROR ++++++++++++++++++++++"
echo "SigNoz requires ports 3301 & 4317 to be open. Please shut down any other service(s) that may be running on these ports."
echo "You can run SigNoz on another port following this guide https://signoz.io/docs/deployment/docker#troubleshooting"
echo "You can run SigNoz on another port following this guide https://signoz.io/docs/install/troubleshooting/"
echo "++++++++++++++++++++++++++++++++++++++++"
echo ""
exit 1
@@ -249,7 +249,7 @@ bye() { # Prints a friendly good bye message and exits the script.
echo ""
echo -e "$sudo_cmd docker-compose -f ./docker/clickhouse-setup/docker-compose.yaml ps -a"
# echo "Please read our troubleshooting guide https://signoz.io/docs/deployment/docker#troubleshooting"
echo "Please read our troubleshooting guide https://signoz.io/docs/install/troubleshooting/"
echo "or reach us for support in #help channel in our Slack Community https://signoz.io/slack"
echo "++++++++++++++++++++++++++++++++++++++++"
@@ -277,7 +277,7 @@ request_sudo() {
echo -e "\n\n🙇 We will need sudo access to complete the installation."
if (( $EUID != 0 )); then
sudo_cmd="sudo"
echo -e "Please enter your sudo password, if prompt."
echo -e "Please enter your sudo password, if prompted."
# $sudo_cmd -l | grep -e "NOPASSWD: ALL" > /dev/null
# if [[ $? -ne 0 ]] && ! $sudo_cmd -v; then
# echo "Need sudo privileges to proceed with the installation."
@@ -500,7 +500,7 @@ if [[ $status_code -ne 200 ]]; then
echo -e "$sudo_cmd docker-compose -f ./docker/clickhouse-setup/docker-compose.yaml ps -a"
echo "Please read our troubleshooting guide https://signoz.io/docs/deployment/docker/#troubleshooting-of-common-issues"
echo "Please read our troubleshooting guide https://signoz.io/docs/install/troubleshooting/"
echo "or reach us on SigNoz for support https://signoz.io/slack"
echo "++++++++++++++++++++++++++++++++++++++++"

View File

@@ -1,4 +1,4 @@
FROM golang:1.17-buster AS builder
FROM golang:1.18-buster AS builder
# LD_FLAGS is passed as argument from Makefile. It will be empty, if no argument passed
ARG LD_FLAGS

View File

@@ -16,6 +16,7 @@ import (
type APIHandlerOptions struct {
DataConnector interfaces.DataConnector
SkipConfig *basemodel.SkipConfig
AppDao dao.ModelDao
RulesManager *rules.Manager
FeatureFlags baseint.FeatureLookup
@@ -32,6 +33,7 @@ func NewAPIHandler(opts APIHandlerOptions) (*APIHandler, error) {
baseHandler, err := baseapp.NewAPIHandler(baseapp.APIHandlerOpts{
Reader: opts.DataConnector,
SkipConfig: opts.SkipConfig,
AppDao: opts.AppDao,
RuleManager: opts.RulesManager,
FeatureFlags: opts.FeatureFlags})
@@ -69,60 +71,65 @@ func (ah *APIHandler) CheckFeature(f string) bool {
}
// RegisterRoutes registers routes for this handler on the given router
func (ah *APIHandler) RegisterRoutes(router *mux.Router) {
func (ah *APIHandler) RegisterRoutes(router *mux.Router, am *baseapp.AuthMiddleware) {
// note: add ee override methods first
// routes available only in ee version
router.HandleFunc("/api/v1/licenses",
baseapp.AdminAccess(ah.listLicenses)).
am.AdminAccess(ah.listLicenses)).
Methods(http.MethodGet)
router.HandleFunc("/api/v1/licenses",
baseapp.AdminAccess(ah.applyLicense)).
am.AdminAccess(ah.applyLicense)).
Methods(http.MethodPost)
router.HandleFunc("/api/v1/featureFlags",
baseapp.OpenAccess(ah.getFeatureFlags)).
am.OpenAccess(ah.getFeatureFlags)).
Methods(http.MethodGet)
router.HandleFunc("/api/v1/loginPrecheck",
baseapp.OpenAccess(ah.precheckLogin)).
am.OpenAccess(ah.precheckLogin)).
Methods(http.MethodGet)
// paid plans specific routes
router.HandleFunc("/api/v1/complete/saml",
baseapp.OpenAccess(ah.receiveSAML)).
am.OpenAccess(ah.receiveSAML)).
Methods(http.MethodPost)
router.HandleFunc("/api/v1/complete/google",
baseapp.OpenAccess(ah.receiveGoogleAuth)).
am.OpenAccess(ah.receiveGoogleAuth)).
Methods(http.MethodGet)
router.HandleFunc("/api/v1/orgs/{orgId}/domains",
baseapp.AdminAccess(ah.listDomainsByOrg)).
am.AdminAccess(ah.listDomainsByOrg)).
Methods(http.MethodGet)
router.HandleFunc("/api/v1/domains",
baseapp.AdminAccess(ah.postDomain)).
am.AdminAccess(ah.postDomain)).
Methods(http.MethodPost)
router.HandleFunc("/api/v1/domains/{id}",
baseapp.AdminAccess(ah.putDomain)).
am.AdminAccess(ah.putDomain)).
Methods(http.MethodPut)
router.HandleFunc("/api/v1/domains/{id}",
baseapp.AdminAccess(ah.deleteDomain)).
am.AdminAccess(ah.deleteDomain)).
Methods(http.MethodDelete)
// base overrides
router.HandleFunc("/api/v1/version", baseapp.OpenAccess(ah.getVersion)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/invite/{token}", baseapp.OpenAccess(ah.getInvite)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/register", baseapp.OpenAccess(ah.registerUser)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/login", baseapp.OpenAccess(ah.loginUser)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/traces/{traceId}", baseapp.ViewAccess(ah.searchTraces)).Methods(http.MethodGet)
router.HandleFunc("/api/v2/metrics/query_range", baseapp.ViewAccess(ah.queryRangeMetricsV2)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/version", am.OpenAccess(ah.getVersion)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/invite/{token}", am.OpenAccess(ah.getInvite)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/register", am.OpenAccess(ah.registerUser)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/login", am.OpenAccess(ah.loginUser)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/traces/{traceId}", am.ViewAccess(ah.searchTraces)).Methods(http.MethodGet)
router.HandleFunc("/api/v2/metrics/query_range", am.ViewAccess(ah.queryRangeMetricsV2)).Methods(http.MethodPost)
ah.APIHandler.RegisterRoutes(router)
// PAT APIs
router.HandleFunc("/api/v1/pat", am.OpenAccess(ah.createPAT)).Methods(http.MethodPost)
router.HandleFunc("/api/v1/pat", am.OpenAccess(ah.getPATs)).Methods(http.MethodGet)
router.HandleFunc("/api/v1/pat/{id}", am.OpenAccess(ah.deletePAT)).Methods(http.MethodDelete)
ah.APIHandler.RegisterRoutes(router, am)
}

View File

@@ -5,6 +5,10 @@ import (
)
func (ah *APIHandler) getFeatureFlags(w http.ResponseWriter, r *http.Request) {
featureSet := ah.FF().GetFeatureFlags()
featureSet, err := ah.FF().GetFeatureFlags()
if err != nil {
ah.HandleError(w, err, http.StatusInternalServerError)
return
}
ah.Respond(w, featureSet)
}

View File

@@ -0,0 +1,107 @@
package api
import (
"context"
"crypto/rand"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/gorilla/mux"
"go.signoz.io/signoz/ee/query-service/model"
"go.signoz.io/signoz/pkg/query-service/auth"
"go.uber.org/zap"
)
func generatePATToken() string {
// Generate a 32-byte random token.
token := make([]byte, 32)
rand.Read(token)
// Encode the token in base64.
encodedToken := base64.StdEncoding.EncodeToString(token)
return encodedToken
}
func (ah *APIHandler) createPAT(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
}
// All the PATs are associated with the user creating the PAT. Hence, the permissions
// associated with the PAT is also equivalent to that of the user.
req.UserID = user.Id
req.CreatedAt = time.Now().Unix()
req.Token = generatePATToken()
zap.S().Debugf("Got PAT request: %+v", req)
if apierr := ah.AppDao().CreatePAT(ctx, &req); apierr != nil {
RespondError(w, apierr, nil)
return
}
ah.Respond(w, &req)
}
func (ah *APIHandler) getPATs(w http.ResponseWriter, r *http.Request) {
ctx := context.Background()
user, err := auth.GetUserFromRequest(r)
if err != nil {
RespondError(w, &model.ApiError{
Typ: model.ErrorUnauthorized,
Err: err,
}, nil)
return
}
zap.S().Infof("Get PATs for user: %+v", user.Id)
pats, apierr := ah.AppDao().ListPATs(ctx, user.Id)
if apierr != nil {
RespondError(w, apierr, nil)
return
}
ah.Respond(w, pats)
}
func (ah *APIHandler) deletePAT(w http.ResponseWriter, r *http.Request) {
ctx := context.Background()
id := mux.Vars(r)["id"]
user, err := auth.GetUserFromRequest(r)
if err != nil {
RespondError(w, &model.ApiError{
Typ: model.ErrorUnauthorized,
Err: err,
}, nil)
return
}
pat, apierr := ah.AppDao().GetPATByID(ctx, id)
if apierr != nil {
RespondError(w, apierr, nil)
return
}
if pat.UserID != user.Id {
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

@@ -22,15 +22,23 @@ import (
"go.signoz.io/signoz/ee/query-service/app/db"
"go.signoz.io/signoz/ee/query-service/dao"
"go.signoz.io/signoz/ee/query-service/interfaces"
baseInterface "go.signoz.io/signoz/pkg/query-service/interfaces"
licensepkg "go.signoz.io/signoz/ee/query-service/license"
"go.signoz.io/signoz/ee/query-service/usage"
"go.signoz.io/signoz/pkg/query-service/agentConf"
baseapp "go.signoz.io/signoz/pkg/query-service/app"
"go.signoz.io/signoz/pkg/query-service/app/dashboards"
baseexplorer "go.signoz.io/signoz/pkg/query-service/app/explorer"
"go.signoz.io/signoz/pkg/query-service/app/opamp"
opAmpModel "go.signoz.io/signoz/pkg/query-service/app/opamp/model"
baseauth "go.signoz.io/signoz/pkg/query-service/auth"
baseconst "go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/healthcheck"
basealm "go.signoz.io/signoz/pkg/query-service/integrations/alertManager"
baseint "go.signoz.io/signoz/pkg/query-service/interfaces"
"go.signoz.io/signoz/pkg/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
pqle "go.signoz.io/signoz/pkg/query-service/pqlEngine"
rules "go.signoz.io/signoz/pkg/query-service/rules"
"go.signoz.io/signoz/pkg/query-service/telemetry"
@@ -38,10 +46,13 @@ import (
"go.uber.org/zap"
)
const AppDbEngine = "sqlite"
type ServerOptions struct {
PromConfigPath string
HTTPHostPort string
PrivateHostPort string
PromConfigPath string
SkipTopLvlOpsPath string
HTTPHostPort string
PrivateHostPort string
// alert specific params
DisableRules bool
RuleRepoURL string
@@ -81,6 +92,8 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
return nil, err
}
baseexplorer.InitWithDSN(baseconst.RELATIONAL_DATASOURCE_PATH)
localDB, err := dashboards.InitDB(baseconst.RELATIONAL_DATASOURCE_PATH)
if err != nil {
@@ -107,7 +120,15 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
go qb.Start(readerReady)
reader = qb
} else {
return nil, fmt.Errorf("Storage type: %s is not supported in query service", storage)
return nil, fmt.Errorf("storage type: %s is not supported in query service", storage)
}
skipConfig := &basemodel.SkipConfig{}
if serverOptions.SkipTopLvlOpsPath != "" {
// read skip config
skipConfig, err = basemodel.ReadSkipConfig(serverOptions.SkipTopLvlOpsPath)
if err != nil {
return nil, err
}
}
<-readerReady
@@ -116,12 +137,24 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
serverOptions.RuleRepoURL,
localDB,
reader,
serverOptions.DisableRules)
serverOptions.DisableRules,
lm)
if err != nil {
return nil, err
}
// initiate opamp
_, err = opAmpModel.InitDB(baseconst.RELATIONAL_DATASOURCE_PATH)
if err != nil {
return nil, err
}
// initiate agent config handler
if err := agentConf.Initiate(localDB, AppDbEngine); err != nil {
return nil, err
}
// start the usagemanager
usageManager, err := usage.New("sqlite", localDB, lm.GetRepo(), reader.GetConn())
if err != nil {
@@ -136,6 +169,7 @@ func NewServer(serverOptions *ServerOptions) (*Server, error) {
apiOpts := api.APIHandlerOptions{
DataConnector: reader,
SkipConfig: skipConfig,
AppDao: modelDao,
RulesManager: rm,
FeatureFlags: lm,
@@ -188,7 +222,7 @@ func (s *Server) createPrivateServer(apiHandler *api.APIHandler) (*http.Server,
// ip here for alert manager
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"GET", "DELETE", "POST", "PUT", "PATCH"},
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type"},
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "SIGNOZ-API-KEY"},
})
handler := c.Handler(r)
@@ -203,13 +237,33 @@ func (s *Server) createPublicServer(apiHandler *api.APIHandler) (*http.Server, e
r := mux.NewRouter()
getUserFromRequest := func(r *http.Request) (*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()
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)
r.Use(setTimeoutMiddleware)
r.Use(s.analyticsMiddleware)
r.Use(loggingMiddleware)
apiHandler.RegisterRoutes(r)
apiHandler.RegisterMetricsRoutes(r)
apiHandler.RegisterLogsRoutes(r)
apiHandler.RegisterRoutes(r, am)
apiHandler.RegisterMetricsRoutes(r, am)
apiHandler.RegisterLogsRoutes(r, am)
apiHandler.RegisterQueryRangeV3Routes(r, am)
c := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
@@ -233,7 +287,7 @@ func loggingMiddleware(next http.Handler) http.Handler {
path, _ := route.GetPathTemplate()
startTime := time.Now()
next.ServeHTTP(w, r)
zap.S().Info(path, "\ttimeTaken: ", time.Now().Sub(startTime))
zap.L().Info(path+"\ttimeTaken:"+time.Now().Sub(startTime).String(), zap.Duration("timeTaken", time.Now().Sub(startTime)), zap.String("path", path))
})
}
@@ -245,7 +299,7 @@ func loggingMiddlewarePrivate(next http.Handler) http.Handler {
path, _ := route.GetPathTemplate()
startTime := time.Now()
next.ServeHTTP(w, r)
zap.S().Info(path, "\tprivatePort: true", "\ttimeTaken: ", time.Now().Sub(startTime))
zap.L().Info(path+"\tprivatePort: true \ttimeTaken"+time.Now().Sub(startTime).String(), zap.Duration("timeTaken", time.Now().Sub(startTime)), zap.String("path", path), zap.Bool("tprivatePort", true))
})
}
@@ -274,7 +328,7 @@ func extractDashboardMetaData(path string, r *http.Request) (map[string]interfac
pathToExtractBodyFrom := "/api/v2/metrics/query_range"
data := map[string]interface{}{}
var postData *model.QueryRangeParamsV2
var postData *basemodel.QueryRangeParamsV2
if path == pathToExtractBodyFrom && (r.Method == "POST") {
if r.Body != nil {
@@ -361,7 +415,7 @@ func setTimeoutMiddleware(next http.Handler) http.Handler {
// check if route is not excluded
url := r.URL.Path
if _, ok := baseconst.TimeoutExcludedRoutes[url]; !ok {
ctx, cancel = context.WithTimeout(r.Context(), baseconst.ContextTimeout*time.Second)
ctx, cancel = context.WithTimeout(r.Context(), baseconst.ContextTimeout)
defer cancel()
}
@@ -447,7 +501,7 @@ func (s *Server) Start() error {
if port, err := utils.GetPort(s.privateConn.Addr()); err == nil {
privatePort = port
}
fmt.Println("starting private http")
go func() {
zap.S().Info("Starting Private HTTP server", zap.Int("port", privatePort), zap.String("addr", s.serverOptions.PrivateHostPort))
@@ -463,6 +517,37 @@ func (s *Server) Start() error {
}()
go func() {
zap.S().Info("Starting OpAmp Websocket server", zap.String("addr", baseconst.OpAmpWsEndpoint))
err := opamp.InitalizeServer(baseconst.OpAmpWsEndpoint, &opAmpModel.AllAgents)
if err != nil {
zap.S().Info("opamp ws server failed to start", err)
s.unavailableChannel <- healthcheck.Unavailable
}
}()
return nil
}
func (s *Server) Stop() error {
if s.httpServer != nil {
if err := s.httpServer.Shutdown(context.Background()); err != nil {
return err
}
}
if s.privateHTTP != nil {
if err := s.privateHTTP.Shutdown(context.Background()); err != nil {
return err
}
}
opamp.StopServer()
if s.ruleManager != nil {
s.ruleManager.Stop()
}
return nil
}
@@ -472,7 +557,8 @@ func makeRulesManager(
ruleRepoURL string,
db *sqlx.DB,
ch baseint.Reader,
disableRules bool) (*rules.Manager, error) {
disableRules bool,
fm baseInterface.FeatureLookup) (*rules.Manager, error) {
// create engine
pqle, err := pqle.FromConfigPath(promConfigPath)
@@ -499,6 +585,7 @@ func makeRulesManager(
Context: context.Background(),
Logger: nil,
DisableRules: disableRules,
FeatureFlags: fm,
}
// create Manager

View File

@@ -3,6 +3,7 @@ package dao
import (
"context"
"net/url"
"github.com/google/uuid"
"github.com/jmoiron/sqlx"
"go.signoz.io/signoz/ee/query-service/model"
@@ -24,7 +25,7 @@ type ModelDao interface {
CanUsePassword(ctx context.Context, email string) (bool, basemodel.BaseApiError)
PrepareSsoRedirect(ctx context.Context, redirectUri, email string) (redirectURL string, apierr basemodel.BaseApiError)
GetDomainFromSsoResponse(ctx context.Context, relayState *url.URL) (*model.OrgDomain, error)
// org domain (auth domains) CRUD ops
ListDomains(ctx context.Context, orgId string) ([]model.OrgDomain, basemodel.BaseApiError)
GetDomain(ctx context.Context, id uuid.UUID) (*model.OrgDomain, basemodel.BaseApiError)
@@ -32,4 +33,11 @@ type ModelDao interface {
UpdateDomain(ctx context.Context, domain *model.OrgDomain) basemodel.BaseApiError
DeleteDomain(ctx context.Context, id uuid.UUID) basemodel.BaseApiError
GetDomainByEmail(ctx context.Context, email string) (*model.OrgDomain, basemodel.BaseApiError)
CreatePAT(ctx context.Context, p *model.PAT) basemodel.BaseApiError
GetPAT(ctx context.Context, pat string) (*model.PAT, basemodel.BaseApiError)
GetPATByID(ctx context.Context, id string) (*model.PAT, basemodel.BaseApiError)
GetUserByPAT(ctx context.Context, token string) (*basemodel.UserPayload, basemodel.BaseApiError)
ListPATs(ctx context.Context, userID string) ([]model.PAT, basemodel.BaseApiError)
DeletePAT(ctx context.Context, id string) basemodel.BaseApiError
}

View File

@@ -48,7 +48,17 @@ func InitDB(dataSourceName string) (*modelDao, error) {
updated_at INTEGER,
data TEXT NOT NULL,
FOREIGN KEY(org_id) REFERENCES organizations(id)
);`
);
CREATE TABLE IF NOT EXISTS personal_access_tokens (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT NOT NULL,
token TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
created_at INTEGER NOT NULL,
expires_at INTEGER NOT NULL,
FOREIGN KEY(user_id) REFERENCES users(id)
);
`
_, err = m.DB().Exec(table_schema)
if err != nil {

View File

@@ -0,0 +1,106 @@
package sqlite
import (
"context"
"fmt"
"go.signoz.io/signoz/ee/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.uber.org/zap"
)
func (m *modelDao) CreatePAT(ctx context.Context, p *model.PAT) basemodel.BaseApiError {
_, err := m.DB().ExecContext(ctx,
"INSERT INTO personal_access_tokens (user_id, token, name, created_at, expires_at) VALUES ($1, $2, $3, $4, $5)",
p.UserID,
p.Token,
p.Name,
p.CreatedAt,
p.ExpiresAt)
if err != nil {
zap.S().Errorf("Failed to insert PAT in db, err: %v", zap.Error(err))
return model.InternalError(fmt.Errorf("PAT insertion failed"))
}
return nil
}
func (m *modelDao) ListPATs(ctx context.Context, userID string) ([]model.PAT, basemodel.BaseApiError) {
pats := []model.PAT{}
if err := m.DB().Select(&pats, `SELECT * FROM personal_access_tokens WHERE user_id=?;`, userID); err != nil {
zap.S().Errorf("Failed to fetch PATs for user: %s, err: %v", userID, zap.Error(err))
return nil, model.InternalError(fmt.Errorf("failed to fetch PATs"))
}
return pats, nil
}
func (m *modelDao) DeletePAT(ctx context.Context, id string) basemodel.BaseApiError {
_, err := m.DB().ExecContext(ctx, `DELETE from personal_access_tokens where id=?;`, id)
if err != nil {
zap.S().Errorf("Failed to delete PAT, err: %v", zap.Error(err))
return model.InternalError(fmt.Errorf("failed to delete PAT"))
}
return nil
}
func (m *modelDao) GetPAT(ctx context.Context, token string) (*model.PAT, basemodel.BaseApiError) {
pats := []model.PAT{}
if err := m.DB().Select(&pats, `SELECT * FROM personal_access_tokens WHERE token=?;`, token); err != nil {
return nil, model.InternalError(fmt.Errorf("failed to fetch PAT"))
}
if len(pats) != 1 {
return nil, &model.ApiError{
Typ: model.ErrorInternal,
Err: fmt.Errorf("found zero or multiple PATs with same token, %s", token),
}
}
return &pats[0], nil
}
func (m *modelDao) GetPATByID(ctx context.Context, id string) (*model.PAT, basemodel.BaseApiError) {
pats := []model.PAT{}
if err := m.DB().Select(&pats, `SELECT * FROM personal_access_tokens WHERE id=?;`, id); err != nil {
return nil, model.InternalError(fmt.Errorf("failed to fetch PAT"))
}
if len(pats) != 1 {
return nil, &model.ApiError{
Typ: model.ErrorInternal,
Err: fmt.Errorf("found zero or multiple PATs with same token"),
}
}
return &pats[0], nil
}
func (m *modelDao) GetUserByPAT(ctx context.Context, token string) (*basemodel.UserPayload, basemodel.BaseApiError) {
users := []basemodel.UserPayload{}
query := `SELECT
u.id,
u.name,
u.email,
u.password,
u.created_at,
u.profile_picture_url,
u.org_id,
u.group_id
FROM users u, personal_access_tokens p
WHERE u.id = p.user_id and p.token=?;`
if err := m.DB().Select(&users, query, token); err != nil {
return nil, model.InternalError(fmt.Errorf("failed to fetch user from PAT, err: %v", err))
}
if len(users) != 1 {
return nil, &model.ApiError{
Typ: model.ErrorInternal,
Err: fmt.Errorf("found zero or multiple users with same PAT token"),
}
}
return &users[0], nil
}

View File

@@ -2,6 +2,7 @@ package license
import (
"context"
"database/sql"
"fmt"
"time"
@@ -9,6 +10,7 @@ import (
"go.signoz.io/signoz/ee/query-service/license/sqlite"
"go.signoz.io/signoz/ee/query-service/model"
basemodel "go.signoz.io/signoz/pkg/query-service/model"
"go.uber.org/zap"
)
@@ -125,3 +127,79 @@ func (r *Repo) UpdatePlanDetails(ctx context.Context,
return nil
}
func (r *Repo) CreateFeature(req *basemodel.Feature) *basemodel.ApiError {
_, err := r.db.Exec(
`INSERT INTO feature_status (name, active, usage, usage_limit, route)
VALUES (?, ?, ?, ?, ?);`,
req.Name, req.Active, req.Usage, req.UsageLimit, req.Route)
if err != nil {
return &basemodel.ApiError{Typ: basemodel.ErrorInternal, Err: err}
}
return nil
}
func (r *Repo) GetFeature(featureName string) (basemodel.Feature, error) {
var feature basemodel.Feature
err := r.db.Get(&feature,
`SELECT * FROM feature_status WHERE name = ?;`, featureName)
if err != nil {
return feature, err
}
if feature.Name == "" {
return feature, basemodel.ErrFeatureUnavailable{Key: featureName}
}
return feature, nil
}
func (r *Repo) GetAllFeatures() ([]basemodel.Feature, error) {
var feature []basemodel.Feature
err := r.db.Select(&feature,
`SELECT * FROM feature_status;`)
if err != nil {
return feature, err
}
return feature, nil
}
func (r *Repo) UpdateFeature(req basemodel.Feature) error {
_, err := r.db.Exec(
`UPDATE feature_status SET active = ?, usage = ?, usage_limit = ?, route = ? WHERE name = ?;`,
req.Active, req.Usage, req.UsageLimit, req.Route, req.Name)
if err != nil {
return err
}
return nil
}
func (r *Repo) InitFeatures(req basemodel.FeatureSet) error {
// get a feature by name, if it doesn't exist, create it. If it does exist, update it.
for _, feature := range req {
currentFeature, err := r.GetFeature(feature.Name)
if err != nil && err == sql.ErrNoRows {
err := r.CreateFeature(&feature)
if err != nil {
return err
}
continue
} else if err != nil {
return err
}
feature.Usage = currentFeature.Usage
if feature.Usage >= feature.UsageLimit && feature.UsageLimit != -1 {
feature.Active = false
}
err = r.UpdateFeature(feature)
if err != nil {
return err
}
}
return nil
}

View File

@@ -96,6 +96,11 @@ func (lm *Manager) SetActive(l *model.License) {
lm.activeFeatures = l.FeatureSet
// set default features
setDefaultFeatures(lm)
err := lm.InitFeatures(lm.activeFeatures)
if err != nil {
zap.S().Panicf("Couldn't activate features: %v", err)
}
if !lm.validatorRunning {
// we want to make sure only one validator runs,
// we already have lock() so good to go
@@ -106,9 +111,7 @@ func (lm *Manager) SetActive(l *model.License) {
}
func setDefaultFeatures(lm *Manager) {
for k, v := range baseconstants.DEFAULT_FEATURE_SET {
lm.activeFeatures[k] = v
}
lm.activeFeatures = append(lm.activeFeatures, baseconstants.DEFAULT_FEATURE_SET...)
}
// LoadActiveLicense loads the most recent active license
@@ -123,8 +126,13 @@ func (lm *Manager) LoadActiveLicense() error {
} else {
zap.S().Info("No active license found, defaulting to basic plan")
// if no active license is found, we default to basic(free) plan with all default features
lm.activeFeatures = basemodel.BasicPlan
lm.activeFeatures = model.BasicPlan
setDefaultFeatures(lm)
err := lm.InitFeatures(lm.activeFeatures)
if err != nil {
zap.S().Error("Couldn't initialize features: ", err)
return err
}
}
return nil
@@ -291,18 +299,31 @@ func (lm *Manager) Activate(ctx context.Context, key string) (licenseResponse *m
// CheckFeature will be internally used by backend routines
// for feature gating
func (lm *Manager) CheckFeature(featureKey string) error {
if value, ok := lm.activeFeatures[featureKey]; ok {
if value {
return nil
}
return basemodel.ErrFeatureUnavailable{Key: featureKey}
feature, err := lm.repo.GetFeature(featureKey)
if err != nil {
return err
}
if feature.Active {
return nil
}
return basemodel.ErrFeatureUnavailable{Key: featureKey}
}
// GetFeatureFlags returns current active features
func (lm *Manager) GetFeatureFlags() basemodel.FeatureSet {
return lm.activeFeatures
func (lm *Manager) GetFeatureFlags() (basemodel.FeatureSet, error) {
return lm.repo.GetAllFeatures()
}
func (lm *Manager) InitFeatures(features basemodel.FeatureSet) error {
return lm.repo.InitFeatures(features)
}
func (lm *Manager) UpdateFeatureFlag(feature basemodel.Feature) error {
return lm.repo.UpdateFeature(feature)
}
func (lm *Manager) GetFeatureFlag(key string) (basemodel.Feature, error) {
return lm.repo.GetFeature(key)
}
// GetRepo return the license repo

View File

@@ -2,6 +2,7 @@ package sqlite
import (
"fmt"
"github.com/jmoiron/sqlx"
)
@@ -33,5 +34,19 @@ func InitDB(db *sqlx.DB) error {
if err != nil {
return fmt.Errorf("Error in creating licenses table: %s", err.Error())
}
table_schema = `CREATE TABLE IF NOT EXISTS feature_status (
name TEXT PRIMARY KEY,
active bool,
usage INTEGER DEFAULT 0,
usage_limit INTEGER DEFAULT 0,
route TEXT
);`
_, err = db.Exec(table_schema)
if err != nil {
return fmt.Errorf("Error in creating feature_status table: %s", err.Error())
}
return nil
}

View File

@@ -3,30 +3,78 @@ package main
import (
"context"
"flag"
"log"
"os"
"os/signal"
"strconv"
"syscall"
"time"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
"go.signoz.io/signoz/ee/query-service/app"
"go.signoz.io/signoz/pkg/query-service/auth"
"go.signoz.io/signoz/pkg/query-service/constants"
baseconst "go.signoz.io/signoz/pkg/query-service/constants"
"go.signoz.io/signoz/pkg/query-service/version"
"google.golang.org/grpc"
zapotlpencoder "github.com/SigNoz/zap_otlp/zap_otlp_encoder"
zapotlpsync "github.com/SigNoz/zap_otlp/zap_otlp_sync"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func initZapLog() *zap.Logger {
func initZapLog(enableQueryServiceLogOTLPExport bool) *zap.Logger {
config := zap.NewDevelopmentConfig()
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
config.EncoderConfig.EncodeDuration = zapcore.StringDurationEncoder
otlpEncoder := zapotlpencoder.NewOTLPEncoder(config.EncoderConfig)
consoleEncoder := zapcore.NewConsoleEncoder(config.EncoderConfig)
defaultLogLevel := zapcore.DebugLevel
config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
config.EncoderConfig.TimeKey = "timestamp"
config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
logger, _ := config.Build()
res := resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String("query-service"),
)
core := zapcore.NewTee(
zapcore.NewCore(consoleEncoder, os.Stdout, defaultLogLevel),
)
if enableQueryServiceLogOTLPExport == true {
conn, err := grpc.DialContext(ctx, constants.OTLPTarget, grpc.WithBlock(), grpc.WithInsecure(), grpc.WithTimeout(time.Second*30))
if err != nil {
log.Println("failed to connect to otlp collector to export query service logs with error:", err)
} else {
logExportBatchSizeInt, err := strconv.Atoi(baseconst.LogExportBatchSize)
if err != nil {
logExportBatchSizeInt = 1000
}
ws := zapcore.AddSync(zapotlpsync.NewOtlpSyncer(conn, zapotlpsync.Options{
BatchSize: logExportBatchSizeInt,
ResourceSchema: semconv.SchemaURL,
Resource: res,
}))
core = zapcore.NewTee(
zapcore.NewCore(consoleEncoder, os.Stdout, defaultLogLevel),
zapcore.NewCore(otlpEncoder, zapcore.NewMultiWriteSyncer(ws), defaultLogLevel),
)
}
}
logger := zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
return logger
}
func main() {
var promConfigPath string
var promConfigPath, skipTopLvlOpsPath string
// disables rule execution but allows change to the rule definition
var disableRules bool
@@ -34,12 +82,16 @@ func main() {
// the url used to build link in the alert messages in slack and other systems
var ruleRepoURL string
var enableQueryServiceLogOTLPExport bool
flag.StringVar(&promConfigPath, "config", "./config/prometheus.yml", "(prometheus config to read metrics)")
flag.StringVar(&skipTopLvlOpsPath, "skip-top-level-ops", "", "(config file to skip top level operations)")
flag.BoolVar(&disableRules, "rules.disable", false, "(disable rule evaluation)")
flag.StringVar(&ruleRepoURL, "rules.repo-url", baseconst.AlertHelpPage, "(host address used to build rule link in alert messages)")
flag.BoolVar(&enableQueryServiceLogOTLPExport, "enable.query.service.log.otlp.export", false, "(enable query service log otlp export)")
flag.Parse()
loggerMgr := initZapLog()
loggerMgr := initZapLog(enableQueryServiceLogOTLPExport)
zap.ReplaceGlobals(loggerMgr)
defer loggerMgr.Sync() // flushes buffer, if any
@@ -47,11 +99,12 @@ func main() {
version.PrintVersion()
serverOptions := &app.ServerOptions{
HTTPHostPort: baseconst.HTTPHostPort,
PromConfigPath: promConfigPath,
PrivateHostPort: baseconst.PrivateHostPort,
DisableRules: disableRules,
RuleRepoURL: ruleRepoURL,
HTTPHostPort: baseconst.HTTPHostPort,
PromConfigPath: promConfigPath,
SkipTopLvlOpsPath: skipTopLvlOpsPath,
PrivateHostPort: baseconst.PrivateHostPort,
DisableRules: disableRules,
RuleRepoURL: ruleRepoURL,
}
// Read the jwt secret key

View File

@@ -0,0 +1,10 @@
package model
type PAT struct {
Id string `json:"id" db:"id"`
UserID string `json:"userId" db:"user_id"`
Token string `json:"token" db:"token"`
Name string `json:"name" db:"name"`
CreatedAt int64 `json:"createdAt" db:"created_at"`
ExpiresAt int64 `json:"expiresAt" db:"expires_at"` // unused as of now
}

View File

@@ -11,21 +11,143 @@ const Enterprise = "ENTERPRISE_PLAN"
const DisableUpsell = "DISABLE_UPSELL"
var BasicPlan = basemodel.FeatureSet{
Basic: true,
SSO: false,
DisableUpsell: false,
basemodel.Feature{
Name: SSO,
Active: false,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.OSS,
Active: false,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: DisableUpsell,
Active: false,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.SmartTraceDetail,
Active: false,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.CustomMetricsFunction,
Active: false,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.QueryBuilderPanels,
Active: true,
Usage: 0,
UsageLimit: 5,
Route: "",
},
basemodel.Feature{
Name: basemodel.QueryBuilderAlerts,
Active: true,
Usage: 0,
UsageLimit: 5,
Route: "",
},
}
var ProPlan = basemodel.FeatureSet{
Pro: true,
SSO: true,
basemodel.SmartTraceDetail: true,
basemodel.CustomMetricsFunction: true,
basemodel.Feature{
Name: SSO,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.OSS,
Active: false,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.SmartTraceDetail,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.CustomMetricsFunction,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.QueryBuilderPanels,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.QueryBuilderAlerts,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
}
var EnterprisePlan = basemodel.FeatureSet{
Enterprise: true,
SSO: true,
basemodel.SmartTraceDetail: true,
basemodel.CustomMetricsFunction: true,
basemodel.Feature{
Name: SSO,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.OSS,
Active: false,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.SmartTraceDetail,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.CustomMetricsFunction,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.QueryBuilderPanels,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.QueryBuilderAlerts,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
}

View File

@@ -1,7 +1,7 @@
{
"presets": [
"@babel/preset-env",
"@babel/preset-react",
["@babel/preset-react", { "runtime": "automatic" }],
"@babel/preset-typescript"
],
"plugins": [

View File

@@ -16,6 +16,7 @@ module.exports = {
'plugin:sonarjs/recommended',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:react/jsx-runtime',
],
parser: '@typescript-eslint/parser',
parserOptions: {

View File

@@ -1 +1,2 @@
network-timeout 600000
save-prefix ""

56
frontend/CONTRIBUTIONS.md Normal file
View File

@@ -0,0 +1,56 @@
# **Frontend Guidelines**
Embrace the spirit of collaboration and contribute to the success of our open-source project by adhering to these frontend development guidelines with precision and passion.
### React and Components
- Strive to create small and modular components, ensuring they are divided into individual pieces for improved maintainability and reusability.
- Avoid passing inline objects or functions as props to React components, as they are recreated with each render cycle.
Utilize careful memoization of functions and variables, balancing optimization efforts to prevent potential performance issues. [When to useMemo and useCallback](https://kentcdodds.com/blog/usememo-and-usecallback) by Kent C. Dodds is quite helpful for this scenario.
- Minimize the use of inline functions whenever possible to enhance code readability and improve overall comprehension.
- Employ the appropriate usage of useMemo and useCallback hooks for effective memoization of values and functions.
- Determine the appropriate placement of components:
- Pages should contain an aggregation of all components and containers.
- Commonly used components should reside in the 'components' directory.
- Parent components responsible for data manipulation should be placed in the 'container' directory.
- Strategically decide where to store data, either in global state or local components:
- Begin by storing data in local components and gradually transition to global state as necessary.
- Avoid importing default namespace `React` as the project is using `v18` and `import React from 'react'` is not needed anymore.
- When a function requires more than three arguments (except when memoized), encapsulate them within an object to enhance readability and reduce potential parameter complexity.
### API and Services
- Avoid incorporating business logic within API/Service files to maintain flexibility for consumers to handle it according to their specific needs.
- Employ the use of the useQuery hook for fetching data and the useMutation hook for updating data, ensuring a consistent and efficient approach.
- Utilize the useQueryClient hook when updating the cache, facilitating smooth and effective management of data within the application.
**Note -** In our project, we are utilizing React Query v3. To gain a comprehensive understanding of its features and implementation, we recommend referring to the [official documentation](https://tanstack.com/query/v3/docs/react/overview) as a valuable resource.
### Styling
- Refrain from using inline styling within React components to maintain separation of concerns and promote a more maintainable codebase.
- Opt for using the rem unit instead of px values to ensure better scalability and responsiveness across different devices and screen sizes.
### Linting and Setup
- It is crucial to refrain from disabling ESLint and TypeScript errors within the project. If there is a specific rule that needs to be disabled, provide a clear and justified explanation for doing so. Maintaining the integrity of the linting and type-checking processes ensures code quality and consistency throughout the codebase.
- In our project, we rely on several essential ESLint plugins, namely:
- [plugin:@typescript-eslint](https://typescript-eslint.io/rules/)
- [airbnb styleguide](https://github.com/airbnb/javascript)
- [plugin:sonarjs](https://github.com/SonarSource/eslint-plugin-sonarjs)
To ensure compliance with our coding standards and best practices, we encourage you to refer to the documentation of these plugins. Familiarizing yourself with the ESLint rules they provide will help maintain code quality and consistency throughout the project.
### Naming Conventions
- Ensure that component names are written in Capital Case, while the folder names should be in lowercase.
- Keep all other elements, such as variables, functions, and file names, in lowercase.
### Miscellaneous
- Ensure that functions are modularized and follow the Single Responsibility Principle (SRP). The function's name should accurately convey its purpose and functionality.
- Semantic division of functions into smaller units should be prioritized for improved readability and maintainability.
Aim to keep functions concise and avoid exceeding a maximum length of 40 lines to enhance code understandability and ease of maintenance.
- Eliminate the use of hard-coded strings or enums, favoring a more flexible and maintainable approach.
- Strive to internationalize all strings within the codebase to support localization and improve accessibility for users across different languages.
- Minimize the usage of multiple if statements or switch cases within a function. Consider creating a mapper and separating logic into multiple functions for better code organization.

View File

@@ -1,5 +1,5 @@
# Builder stage
FROM node:16.15.0-slim as builder
FROM node:16.15.0 as builder
# Add Maintainer Info
LABEL maintainer="signoz"
@@ -11,6 +11,8 @@ WORKDIR /frontend
# Copy the package.json and .yarnrc files prior to install dependencies
COPY package.json ./
# Copy lock file
COPY yarn.lock ./
COPY .yarnrc ./
# Install the dependencies and make the folder

View File

@@ -1,5 +1,20 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable object-shorthand */
/* eslint-disable func-names */
/**
* Adds custom matchers from the react testing library to all tests
*/
import '@testing-library/jest-dom';
import 'jest-styled-components';
// Mock window.matchMedia
window.matchMedia =
window.matchMedia ||
function (): any {
return {
matches: false,
addListener: function () {},
removeListener: function () {},
};
};

View File

@@ -32,7 +32,9 @@
"@grafana/data": "^8.4.3",
"@monaco-editor/react": "^4.3.1",
"@xstate/react": "^3.0.0",
"ansi-to-html": "0.7.2",
"antd": "5.0.5",
"antd-table-saveas-excel": "2.2.1",
"axios": "^0.21.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.6.0",
@@ -47,14 +49,11 @@
"cross-env": "^7.0.3",
"css-loader": "4.3.0",
"css-minimizer-webpack-plugin": "^3.2.0",
"d3": "^6.2.0",
"d3-flame-graph": "^3.1.1",
"d3-tip": "^0.9.1",
"dayjs": "^1.10.7",
"dompurify": "3.0.0",
"dotenv": "8.2.0",
"event-source-polyfill": "1.0.31",
"file-loader": "6.1.1",
"flat": "^5.0.2",
"fontfaceobserver": "2.3.0",
"history": "4.10.1",
"html-webpack-plugin": "5.1.0",
@@ -67,10 +66,10 @@
"less-loader": "^10.2.0",
"lodash-es": "^4.17.21",
"mini-css-extract-plugin": "2.4.5",
"papaparse": "5.4.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-force-graph": "^1.41.0",
"react-graph-vis": "^1.0.5",
"react-grid-layout": "^1.3.4",
"react-i18next": "^11.16.1",
"react-intersection-observer": "9.4.1",
@@ -124,15 +123,14 @@
"@types/color": "^3.0.3",
"@types/compression-webpack-plugin": "^9.0.0",
"@types/copy-webpack-plugin": "^8.0.1",
"@types/d3": "^6.2.0",
"@types/d3-tip": "^3.5.5",
"@types/dompurify": "^2.4.0",
"@types/event-source-polyfill": "^1.0.0",
"@types/flat": "^5.0.2",
"@types/fontfaceobserver": "2.1.0",
"@types/jest": "^27.5.1",
"@types/lodash-es": "^4.17.4",
"@types/mini-css-extract-plugin": "^2.5.1",
"@types/node": "^16.10.3",
"@types/papaparse": "5.3.7",
"@types/react": "18.0.26",
"@types/react-dom": "18.0.10",
"@types/react-grid-layout": "^1.1.2",
@@ -141,7 +139,6 @@
"@types/react-router-dom": "^5.1.6",
"@types/styled-components": "^5.1.4",
"@types/uuid": "^8.3.1",
"@types/vis": "^4.21.21",
"@types/webpack": "^5.28.0",
"@types/webpack-dev-server": "^4.3.0",
"@typescript-eslint/eslint-plugin": "^4.28.2",
@@ -171,7 +168,6 @@
"is-ci": "^3.0.1",
"jest-playwright-preset": "^1.7.0",
"jest-styled-components": "^7.0.8",
"less-plugin-npm-import": "^2.1.0",
"lint-staged": "^12.3.7",
"portfinder-sync": "^0.0.2",
"prettier": "2.2.1",

View File

@@ -0,0 +1,11 @@
{
"options_menu": {
"options": "Options",
"format": "Format",
"row": "Row",
"default": "Default",
"column": "Column",
"maxLines": "Max lines per Row",
"addColumn": "Add a column"
}
}

View File

@@ -0,0 +1,11 @@
{
"options_menu": {
"options": "Options",
"format": "Format",
"row": "Row",
"default": "Default",
"column": "Column",
"maxLines": "Max lines per Row",
"addColumn": "Add a column"
}
}

View File

@@ -7,7 +7,7 @@ import { LOCALSTORAGE } from 'constants/localStorage';
import ROUTES from 'constants/routes';
import { useNotifications } from 'hooks/useNotifications';
import history from 'lib/history';
import React, { useEffect, useMemo } from 'react';
import { ReactChild, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux';
import { matchPath, Redirect, useLocation } from 'react-router-dom';
@@ -161,7 +161,7 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element {
}
interface PrivateRouteProps {
children: React.ReactChild;
children: ReactChild;
}
export default PrivateRoute;

View File

@@ -4,8 +4,10 @@ import Spinner from 'components/Spinner';
import AppLayout from 'container/AppLayout';
import { useThemeConfig } from 'hooks/useDarkMode';
import { NotificationProvider } from 'hooks/useNotifications';
import { ResourceProvider } from 'hooks/useResourceAttribute';
import history from 'lib/history';
import React, { Suspense } from 'react';
import { QueryBuilderProvider } from 'providers/QueryBuilder';
import { Suspense } from 'react';
import { Route, Router, Switch } from 'react-router-dom';
import PrivateRoute from './Private';
@@ -16,28 +18,32 @@ function App(): JSX.Element {
return (
<ConfigProvider theme={themeConfig}>
<NotificationProvider>
<Router history={history}>
<Router history={history}>
<NotificationProvider>
<PrivateRoute>
<AppLayout>
<Suspense fallback={<Spinner size="large" tip="Loading..." />}>
<Switch>
{routes.map(({ path, component, exact }) => (
<Route
key={`${path}`}
exact={exact}
path={path}
component={component}
/>
))}
<ResourceProvider>
<QueryBuilderProvider>
<AppLayout>
<Suspense fallback={<Spinner size="large" tip="Loading..." />}>
<Switch>
{routes.map(({ path, component, exact }) => (
<Route
key={`${path}`}
exact={exact}
path={path}
component={component}
/>
))}
<Route path="*" component={NotFound} />
</Switch>
</Suspense>
</AppLayout>
<Route path="*" component={NotFound} />
</Switch>
</Suspense>
</AppLayout>
</QueryBuilderProvider>
</ResourceProvider>
</PrivateRoute>
</Router>
</NotificationProvider>
</NotificationProvider>
</Router>
</ConfigProvider>
);
}

View File

@@ -15,6 +15,11 @@ export const ServiceMapPage = Loadable(
() => import(/* webpackChunkName: "ServiceMapPage" */ 'modules/Servicemap'),
);
export const TracesExplorer = Loadable(
() =>
import(/* webpackChunkName: "Traces Explorer Page" */ 'pages/TracesExplorer'),
);
export const TraceFilter = Loadable(
() => import(/* webpackChunkName: "Trace Filter Page" */ 'pages/Trace'),
);
@@ -101,6 +106,10 @@ export const Logs = Loadable(
() => import(/* webpackChunkName: "Logs" */ 'pages/Logs'),
);
export const LogsExplorer = Loadable(
() => import(/* webpackChunkName: "Logs Explorer" */ 'pages/LogsExplorer'),
);
export const Login = Loadable(
() => import(/* webpackChunkName: "Login" */ 'pages/Login'),
);

View File

@@ -16,6 +16,7 @@ import {
ListAllALertsPage,
Login,
Logs,
LogsExplorer,
MySettings,
NewDashboardPage,
OrganizationSettings,
@@ -29,6 +30,7 @@ import {
StatusPage,
TraceDetail,
TraceFilter,
TracesExplorer,
UnAuthorized,
UsageExplorerPage,
} from './pageComponents';
@@ -139,6 +141,13 @@ const routes: AppRoutes[] = [
isPrivate: true,
key: 'TRACE',
},
{
path: ROUTES.TRACES_EXPLORER,
exact: true,
component: TracesExplorer,
isPrivate: true,
key: 'TRACES_EXPLORER',
},
{
path: ROUTES.CHANNELS_NEW,
exact: true,
@@ -209,6 +218,13 @@ const routes: AppRoutes[] = [
key: 'LOGS',
isPrivate: true,
},
{
path: ROUTES.LOGS_EXPLORER,
exact: true,
component: LogsExplorer,
key: 'LOGS_EXPLORER',
isPrivate: true,
},
{
path: ROUTES.LOGIN,
exact: true,

View File

@@ -16,7 +16,7 @@ export function ErrorResponseHandler(error: AxiosError): ErrorResponse {
return {
statusCode,
payload: null,
error: 'Not Found',
error: data.errorType,
message: null,
};
}

View File

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

View File

@@ -1,7 +1,6 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import createQueryParams from 'lib/createQueryParams';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/errors/getAll';
@@ -9,11 +8,17 @@ const getAll = async (
props: Props,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
const response = await axios.get(
`/listErrors?${createQueryParams({
...props,
})}`,
);
const response = await axios.post(`/listErrors`, {
start: `${props.start}`,
end: `${props.end}`,
order: props.order,
orderParam: props.orderParam,
limit: props.limit,
offset: props.offset,
exceptionType: props.exceptionType,
serviceName: props.serviceName,
tags: props.tags,
});
return {
statusCode: 200,

View File

@@ -1,7 +1,6 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import createQueryParams from 'lib/createQueryParams';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/errors/getErrorCounts';
@@ -9,11 +8,13 @@ const getErrorCounts = async (
props: Props,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
const response = await axios.get(
`/countErrors?${createQueryParams({
...props,
})}`,
);
const response = await axios.post(`/countErrors`, {
start: `${props.start}`,
end: `${props.end}`,
exceptionType: props.exceptionType,
serviceName: props.serviceName,
tags: props.tags,
});
return {
statusCode: 200,

View File

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

View File

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

View File

@@ -1,17 +1,17 @@
import { ApiV2Instance as axios } from 'api';
import { ApiV3Instance as axios } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
MetricRangePayloadProps,
MetricRangePayloadV3,
MetricsRangeProps,
} from 'types/api/metrics/getQueryRange';
export const getMetricsQueryRange = async (
props: MetricsRangeProps,
): Promise<SuccessResponse<MetricRangePayloadProps> | ErrorResponse> => {
): Promise<SuccessResponse<MetricRangePayloadV3> | ErrorResponse> => {
try {
const response = await axios.post(`/metrics/query_range`, props);
const response = await axios.post('/query_range', props);
return {
statusCode: 200,

View File

@@ -0,0 +1,49 @@
import { ApiV3Instance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError, AxiosResponse } from 'axios';
import { baseAutoCompleteIdKeysOrder } from 'constants/queryBuilder';
import { createIdFromObjectFields } from 'lib/createIdFromObjectFields';
import createQueryParams from 'lib/createQueryParams';
// ** Helpers
import { ErrorResponse, SuccessResponse } from 'types/api';
// ** Types
import { IGetAggregateAttributePayload } from 'types/api/queryBuilder/getAggregatorAttribute';
import {
BaseAutocompleteData,
IQueryAutocompleteResponse,
} from 'types/api/queryBuilder/queryAutocompleteResponse';
export const getAggregateAttribute = async ({
aggregateOperator,
searchText,
dataSource,
}: IGetAggregateAttributePayload): Promise<
SuccessResponse<IQueryAutocompleteResponse> | ErrorResponse
> => {
try {
const response: AxiosResponse<{
data: IQueryAutocompleteResponse;
}> = await ApiV3Instance.get(
`autocomplete/aggregate_attributes?${createQueryParams({
aggregateOperator,
searchText,
dataSource,
})}`,
);
const payload: BaseAutocompleteData[] =
response.data.data.attributeKeys?.map(({ id: _, ...item }) => ({
...item,
id: createIdFromObjectFields(item, baseAutoCompleteIdKeysOrder),
})) || [];
return {
statusCode: 200,
error: null,
message: response.statusText,
payload: { attributeKeys: payload },
};
} catch (e) {
return ErrorResponseHandler(e as AxiosError);
}
};

View File

@@ -0,0 +1,51 @@
import { ApiV3Instance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError, AxiosResponse } from 'axios';
import { baseAutoCompleteIdKeysOrder } from 'constants/queryBuilder';
import { createIdFromObjectFields } from 'lib/createIdFromObjectFields';
import createQueryParams from 'lib/createQueryParams';
import { ErrorResponse, SuccessResponse } from 'types/api';
// ** Types
import { IGetAttributeKeysPayload } from 'types/api/queryBuilder/getAttributeKeys';
import {
BaseAutocompleteData,
IQueryAutocompleteResponse,
} from 'types/api/queryBuilder/queryAutocompleteResponse';
export const getAggregateKeys = async ({
aggregateOperator,
searchText,
dataSource,
aggregateAttribute,
tagType,
}: IGetAttributeKeysPayload): Promise<
SuccessResponse<IQueryAutocompleteResponse> | ErrorResponse
> => {
try {
const response: AxiosResponse<{
data: IQueryAutocompleteResponse;
}> = await ApiV3Instance.get(
`autocomplete/attribute_keys?${createQueryParams({
aggregateOperator,
searchText,
dataSource,
aggregateAttribute,
})}&tagType=${tagType}`,
);
const payload: BaseAutocompleteData[] =
response.data.data.attributeKeys?.map(({ id: _, ...item }) => ({
...item,
id: createIdFromObjectFields(item, baseAutoCompleteIdKeysOrder),
})) || [];
return {
statusCode: 200,
error: null,
message: response.statusText,
payload: { attributeKeys: payload },
};
} catch (e) {
return ErrorResponseHandler(e as AxiosError);
}
};

View File

@@ -0,0 +1,42 @@
import { ApiV3Instance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import createQueryParams from 'lib/createQueryParams';
import { ErrorResponse, SuccessResponse } from 'types/api';
import {
IAttributeValuesResponse,
IGetAttributeValuesPayload,
} from 'types/api/queryBuilder/getAttributesValues';
export const getAttributesValues = async ({
aggregateOperator,
dataSource,
aggregateAttribute,
attributeKey,
filterAttributeKeyDataType,
tagType,
searchText,
}: IGetAttributeValuesPayload): Promise<
SuccessResponse<IAttributeValuesResponse> | ErrorResponse
> => {
try {
const response = await ApiV3Instance.get(
`/autocomplete/attribute_values?${createQueryParams({
aggregateOperator,
dataSource,
aggregateAttribute,
attributeKey,
searchText,
})}&filterAttributeKeyDataType=${filterAttributeKeyDataType}&tagType=${tagType}`,
);
return {
statusCode: 200,
error: null,
message: response.data.status,
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};

View File

@@ -10,7 +10,7 @@ const getSpans = async (
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
const updatedSelectedTags = props.selectedTags.map((e) => ({
Key: e.Key,
Key: `${e.Key}.(string)`,
Operator: e.Operator,
StringValues: e.StringValues,
NumberValues: e.NumberValues,

View File

@@ -28,7 +28,7 @@ const getSpanAggregate = async (
});
const updatedSelectedTags = props.selectedTags.map((e) => ({
Key: e.Key,
Key: `${e.Key}.(string)`,
Operator: e.Operator,
StringValues: e.StringValues,
NumberValues: e.NumberValues,

View File

@@ -14,7 +14,6 @@ const signup = async (
const response = await axios.post(`/register`, {
...props,
});
console.log(' response.data.data', response.data.data);
return {
statusCode: 200,
error: null,

View File

@@ -1,5 +1,3 @@
import React from 'react';
function TimeSeries(): JSX.Element {
return (
<svg

View File

@@ -1,4 +1,4 @@
import React from 'react';
import { CSSProperties } from 'react';
function Value(props: ValueProps): JSX.Element {
const { fillColor } = props;
@@ -20,7 +20,7 @@ function Value(props: ValueProps): JSX.Element {
}
interface ValueProps {
fillColor: React.CSSProperties['color'];
fillColor: CSSProperties['color'];
}
export default Value;

View File

@@ -1,5 +1,3 @@
import React from 'react';
function NotFound(): JSX.Element {
return (
<svg

View File

@@ -1,5 +1,3 @@
import React from 'react';
function SomethingWentWrong(): JSX.Element {
return (
<svg

View File

@@ -1,5 +1,3 @@
import React from 'react';
function UnAuthorized(): JSX.Element {
return (
<svg

View File

@@ -0,0 +1,59 @@
import { render, screen } from '@testing-library/react';
import { useIsDarkMode } from 'hooks/useDarkMode';
import Editor from './index';
jest.mock('hooks/useDarkMode', () => ({
useIsDarkMode: jest.fn(),
}));
describe('Editor', () => {
it('renders correctly with default props', () => {
const { container } = render(<Editor value="" />);
expect(container).toMatchSnapshot();
});
it('renders correctly with custom props', () => {
const customProps = {
value: 'test',
language: 'javascript',
readOnly: true,
height: '50vh',
options: { minimap: { enabled: false } },
};
const { container } = render(
<Editor
value={customProps.value}
height={customProps.height}
language={customProps.language}
options={customProps.options}
readOnly={customProps.readOnly}
/>,
);
expect(container).toMatchSnapshot();
});
it('renders with dark mode theme', () => {
(useIsDarkMode as jest.Mock).mockImplementation(() => true);
const { container } = render(<Editor value="dark mode text" />);
expect(container).toMatchSnapshot();
});
it('renders with light mode theme', () => {
(useIsDarkMode as jest.Mock).mockImplementation(() => false);
const { container } = render(<Editor value="light mode text" />);
expect(container).toMatchSnapshot();
});
it('displays "Loading..." message initially', () => {
const { rerender } = render(<Editor value="initial text" />);
expect(screen.getByText('Loading...')).toBeInTheDocument();
rerender(<Editor value="initial text" />);
});
});

View File

@@ -0,0 +1,69 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Editor renders correctly with custom props 1`] = `
<div>
<section
style="display: flex; position: relative; text-align: initial; width: 100%; height: 50vh;"
>
<div
style="display: flex; height: 100%; width: 100%; justify-content: center; align-items: center;"
>
Loading...
</div>
<div
style="width: 100%; display: none;"
/>
</section>
</div>
`;
exports[`Editor renders correctly with default props 1`] = `
<div>
<section
style="display: flex; position: relative; text-align: initial; width: 100%; height: 40vh;"
>
<div
style="display: flex; height: 100%; width: 100%; justify-content: center; align-items: center;"
>
Loading...
</div>
<div
style="width: 100%; display: none;"
/>
</section>
</div>
`;
exports[`Editor renders with dark mode theme 1`] = `
<div>
<section
style="display: flex; position: relative; text-align: initial; width: 100%; height: 40vh;"
>
<div
style="display: flex; height: 100%; width: 100%; justify-content: center; align-items: center;"
>
Loading...
</div>
<div
style="width: 100%; display: none;"
/>
</section>
</div>
`;
exports[`Editor renders with light mode theme 1`] = `
<div>
<section
style="display: flex; position: relative; text-align: initial; width: 100%; height: 40vh;"
>
<div
style="display: flex; height: 100%; width: 100%; justify-content: center; align-items: center;"
>
Loading...
</div>
<div
style="width: 100%; display: none;"
/>
</section>
</div>
`;

View File

@@ -1,6 +1,6 @@
import MEditor, { EditorProps } from '@monaco-editor/react';
import { useIsDarkMode } from 'hooks/useDarkMode';
import React from 'react';
import { useMemo } from 'react';
function Editor({
value,
@@ -11,16 +11,27 @@ function Editor({
options,
}: MEditorProps): JSX.Element {
const isDarkMode = useIsDarkMode();
const onChangeHandler = (newValue?: string): void => {
if (readOnly) return;
if (typeof newValue === 'string' && onChange) onChange(newValue);
};
const editorOptions = useMemo(
() => ({ fontSize: 16, automaticLayout: true, readOnly, ...options }),
[options, readOnly],
);
return (
<MEditor
theme={isDarkMode ? 'vs-dark' : 'vs-light'}
language={language}
value={value}
options={{ fontSize: 16, automaticLayout: true, readOnly, ...options }}
options={editorOptions}
height={height}
onChange={(newValue): void => {
if (typeof newValue === 'string') onChange(newValue);
}}
onChange={onChangeHandler}
data-testid="monaco-editor"
/>
);
}
@@ -28,7 +39,7 @@ function Editor({
interface MEditorProps {
value: string;
language?: string;
onChange: (value: string) => void;
onChange?: (value: string) => void;
readOnly?: boolean;
height?: string;
options?: EditorProps['options'];
@@ -39,6 +50,7 @@ Editor.defaultProps = {
readOnly: false,
height: '40vh',
options: {},
onChange: (): void => {},
};
export default Editor;

View File

@@ -0,0 +1,46 @@
import {
ActiveElement,
ChartTypeRegistry,
Point,
TooltipModel,
TooltipXAlignment,
TooltipYAlignment,
} from 'chart.js';
export function TooltipPosition(
this: TooltipModel<keyof ChartTypeRegistry>,
_: readonly ActiveElement[],
eventPosition: Point,
): ITooltipPosition {
const {
chartArea: { width },
scales: { x, y },
} = this.chart;
const valueForPixelOnX = Number(x.getValueForPixel(eventPosition.x));
const valueForPixelonY = Number(y.getValueForPixel(eventPosition.y));
const rightmostWidth = this.width + x.getPixelForValue(valueForPixelOnX) + 20;
if (rightmostWidth > width) {
return {
x: x.getPixelForValue(valueForPixelOnX) - 20,
y: y.getPixelForValue(valueForPixelonY) + 10,
xAlign: 'right',
yAlign: 'top',
};
}
return {
x: x.getPixelForValue(valueForPixelOnX) + 20,
y: y.getPixelForValue(valueForPixelonY) + 10,
xAlign: 'left',
yAlign: 'top',
};
}
interface ITooltipPosition {
x: number;
y: number;
xAlign: TooltipXAlignment;
yAlign: TooltipYAlignment;
}

View File

@@ -26,7 +26,7 @@ import annotationPlugin from 'chartjs-plugin-annotation';
import dayjs from 'dayjs';
import { useIsDarkMode } from 'hooks/useDarkMode';
import isEqual from 'lodash-es/isEqual';
import React, { memo, useCallback, useEffect, useRef } from 'react';
import { memo, useCallback, useEffect, useRef } from 'react';
import { hasData } from './hasData';
import { getAxisLabelColor } from './helpers';
@@ -44,6 +44,7 @@ import {
intersectionCursorPluginId,
IntersectionCursorPluginOptions,
} from './Plugin/IntersectionCursor';
import { TooltipPosition as TooltipPositionHandler } from './Plugin/Tooltip';
import { LegendsContainer } from './styles';
import { useXAxisTimeUnit } from './xAxisConfig';
import { getToolTipValue, getYAxisFormattedValue } from './yAxisConfig';
@@ -67,6 +68,8 @@ Chart.register(
annotationPlugin,
);
Tooltip.positioners.custom = TooltipPositionHandler;
function Graph({
animate = true,
data,
@@ -177,6 +180,10 @@ function Graph({
return 'rgba(255, 255, 255, 0.75)';
},
},
position: 'custom',
itemSort(item1, item2) {
return item2.parsed.y - item1.parsed.y;
},
},
[dragSelectPluginId]: createDragSelectPluginOptions(
!!onDragSelect,
@@ -324,6 +331,12 @@ function Graph({
);
}
declare module 'chart.js' {
interface TooltipPositionerMap {
custom: TooltipPositionerFunction<ChartType>;
}
}
type CustomChartOptions = ChartOptions & {
plugins: {
[dragSelectPluginId]: DragSelectPluginOptions | false;

View File

@@ -1,5 +1,12 @@
import { Form, Input, InputProps, InputRef } from 'antd';
import React from 'react';
import {
ChangeEventHandler,
FocusEventHandler,
KeyboardEventHandler,
LegacyRef,
ReactNode,
Ref,
} from 'react';
function InputComponent({
value,
@@ -22,7 +29,7 @@ function InputComponent({
type={type}
onChange={onChangeHandler}
value={value}
ref={ref as React.Ref<InputRef>}
ref={ref as Ref<InputRef>}
size={size}
addonBefore={addonBefore}
onBlur={onBlurHandler}
@@ -37,15 +44,15 @@ function InputComponent({
interface InputComponentProps extends InputProps {
value: InputProps['value'];
type?: InputProps['type'];
onChangeHandler?: React.ChangeEventHandler<HTMLInputElement>;
onChangeHandler?: ChangeEventHandler<HTMLInputElement>;
placeholder?: InputProps['placeholder'];
ref?: React.LegacyRef<InputRef>;
ref?: LegacyRef<InputRef>;
size?: InputProps['size'];
onBlurHandler?: React.FocusEventHandler<HTMLInputElement>;
onPressEnterHandler?: React.KeyboardEventHandler<HTMLInputElement>;
onBlurHandler?: FocusEventHandler<HTMLInputElement>;
onPressEnterHandler?: KeyboardEventHandler<HTMLInputElement>;
label?: string;
labelOnTop?: boolean;
addonBefore?: React.ReactNode;
addonBefore?: ReactNode;
}
InputComponent.defaultProps = {

View File

@@ -0,0 +1,49 @@
import {
render,
screen,
waitForElementToBeRemoved,
} from '@testing-library/react';
import React, { ComponentType, Suspense } from 'react';
import Loadable from './index';
// Sample component to be loaded lazily
function SampleComponent(): JSX.Element {
return <div>Sample Component</div>;
}
const loadSampleComponent = (): Promise<{
default: ComponentType;
}> =>
new Promise<{ default: ComponentType }>((resolve) => {
setTimeout(() => {
resolve({ default: SampleComponent });
}, 500);
});
describe('Loadable', () => {
it('should render the lazily loaded component', async () => {
const LoadableSampleComponent = Loadable(loadSampleComponent);
const { container } = render(
<Suspense fallback={<div>Loading...</div>}>
<LoadableSampleComponent />
</Suspense>,
);
expect(screen.getByText('Loading...')).toBeInTheDocument();
await waitForElementToBeRemoved(() => screen.queryByText('Loading...'));
expect(container.querySelector('div')).toHaveTextContent('Sample Component');
});
it('should call lazy with the provided import path', () => {
const reactLazySpy = jest.spyOn(React, 'lazy');
Loadable(loadSampleComponent);
expect(reactLazySpy).toHaveBeenCalledTimes(1);
expect(reactLazySpy).toHaveBeenCalledWith(expect.any(Function));
reactLazySpy.mockRestore();
});
});

View File

@@ -1,8 +1,8 @@
import { ComponentType, lazy } from 'react';
import { ComponentType, lazy, LazyExoticComponent } from 'react';
function Loadable(importPath: {
(): LoadableProps;
}): React.LazyExoticComponent<LazyComponent> {
}): LazyExoticComponent<LazyComponent> {
return lazy(() => importPath());
}

View File

@@ -1,13 +1,14 @@
import { Button, Popover } from 'antd';
import { Popover } from 'antd';
import ROUTES from 'constants/routes';
import history from 'lib/history';
import { generateFilterQuery } from 'lib/logs/generateFilterQuery';
import React, { memo, useCallback, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Dispatch } from 'redux';
import { memo, ReactNode, useCallback, useMemo } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import AppActions from 'types/actions';
import { SET_SEARCH_QUERY_STRING } from 'types/actions/logs';
import { ILogsReducer } from 'types/reducer/logs';
import { ButtonContainer } from './styles';
function AddToQueryHOC({
fieldKey,
fieldValue,
@@ -16,7 +17,6 @@ function AddToQueryHOC({
const {
searchFilter: { queryString },
} = useSelector<AppState, ILogsReducer>((store) => store.logs);
const dispatch = useDispatch<Dispatch<AppActions>>();
const generatedQuery = useMemo(
() => generateFilterQuery({ fieldKey, fieldValue, type: 'IN' }),
@@ -31,31 +31,27 @@ function AddToQueryHOC({
} else {
updatedQueryString += ` AND ${generatedQuery}`;
}
dispatch({
type: SET_SEARCH_QUERY_STRING,
payload: {
searchQueryString: updatedQueryString,
},
});
}, [dispatch, generatedQuery, queryString]);
history.replace(`${ROUTES.LOGS}?q=${updatedQueryString}`);
}, [generatedQuery, queryString]);
const popOverContent = useMemo(() => <span>Add to query: {fieldKey}</span>, [
fieldKey,
]);
return (
<Button size="small" type="text" onClick={handleQueryAdd}>
<ButtonContainer size="small" type="text" onClick={handleQueryAdd}>
<Popover placement="top" content={popOverContent}>
{children}
</Popover>
</Button>
</ButtonContainer>
);
}
interface AddToQueryHOCProps {
fieldKey: string;
fieldValue: string;
children: React.ReactNode;
children: ReactNode;
}
export default memo(AddToQueryHOC);

View File

@@ -1,9 +1,9 @@
import React from 'react';
import { ReactNode } from 'react';
import { CategoryHeadingText } from './styles';
interface ICategoryHeadingProps {
children: React.ReactNode;
children: ReactNode;
}
function CategoryHeading({ children }: ICategoryHeadingProps): JSX.Element {
return <CategoryHeadingText type="secondary">{children}</CategoryHeadingText>;

View File

@@ -1,6 +1,6 @@
import { Popover } from 'antd';
import { useNotifications } from 'hooks/useNotifications';
import React, { useCallback, useEffect } from 'react';
import { ReactNode, useCallback, useEffect } from 'react';
import { useCopyToClipboard } from 'react-use';
function CopyClipboardHOC({
@@ -22,7 +22,7 @@ function CopyClipboardHOC({
}, [setCopy, textToCopy]);
return (
<span onClick={onClick} onKeyDown={onClick} role="button" tabIndex={0}>
<span onClick={onClick} role="presentation" tabIndex={-1}>
<Popover
placement="top"
content={<span style={{ fontSize: '0.9rem' }}>Copy to clipboard</span>}
@@ -35,7 +35,7 @@ function CopyClipboardHOC({
interface CopyClipboardHOCProps {
textToCopy: string;
children: React.ReactNode;
children: ReactNode;
}
export default CopyClipboardHOC;

View File

@@ -1,12 +1,13 @@
import { blue, grey, orange } from '@ant-design/colors';
import { CopyFilled, ExpandAltOutlined } from '@ant-design/icons';
import Convert from 'ansi-to-html';
import { Button, Divider, Row, Typography } from 'antd';
import { map } from 'd3';
import dayjs from 'dayjs';
import dompurify from 'dompurify';
import { useNotifications } from 'hooks/useNotifications';
// utils
import { FlatLogData } from 'lib/logs/flatLogData';
import React, { useCallback, useMemo } from 'react';
import { useCallback, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useCopyToClipboard } from 'react-use';
// interfaces
@@ -19,24 +20,37 @@ import { ILogsReducer } from 'types/reducer/logs';
import AddToQueryHOC from '../AddToQueryHOC';
import CopyClipboardHOC from '../CopyClipboardHOC';
// styles
import { Container, LogContainer, Text, TextContainer } from './styles';
import {
Container,
LogContainer,
LogText,
SelectedLog,
Text,
TextContainer,
} from './styles';
import { isValidLogField } from './util';
const convert = new Convert();
interface LogFieldProps {
fieldKey: string;
fieldValue: string;
}
function LogGeneralField({ fieldKey, fieldValue }: LogFieldProps): JSX.Element {
const html = useMemo(
() => ({
__html: convert.toHtml(dompurify.sanitize(fieldValue)),
}),
[fieldValue],
);
return (
<TextContainer>
<Text ellipsis type="secondary">
{fieldKey}
{`${fieldKey}: `}
</Text>
<CopyClipboardHOC textToCopy={fieldValue}>
<Typography.Text ellipsis>
{': '}
{fieldValue}
</Typography.Text>
<LogText dangerouslySetInnerHTML={html} />
</CopyClipboardHOC>
</TextContainer>
);
@@ -47,31 +61,19 @@ function LogSelectedField({
fieldValue = '',
}: LogFieldProps): JSX.Element {
return (
<div
style={{
display: 'flex',
overflow: 'hidden',
width: '100%',
}}
>
<SelectedLog>
<AddToQueryHOC fieldKey={fieldKey} fieldValue={fieldValue}>
<Typography.Text>
{`"`}
<span style={{ color: blue[4] }}>{fieldKey}</span>
{`"`}
</Typography.Text>
</AddToQueryHOC>
<CopyClipboardHOC textToCopy={fieldValue}>
<Typography.Text ellipsis>
<span>
{': '}
{typeof fieldValue === 'string' && `"`}
</span>
<span style={{ color: orange[6] }}>{fieldValue}</span>
{typeof fieldValue === 'string' && `"`}
<span>{': '}</span>
<span style={{ color: orange[6] }}>{fieldValue || "''"}</span>
</Typography.Text>
</CopyClipboardHOC>
</div>
</SelectedLog>
);
}
@@ -103,27 +105,28 @@ function ListLogView({ logData }: ListLogViewProps): JSX.Element {
});
};
const updatedSelecedFields = useMemo(
() => selected.filter((e) => e.name !== 'id'),
[selected],
);
return (
<Container>
<div>
<LogContainer>
<>
<LogGeneralField fieldKey="log" fieldValue={flattenLogData.body} />
{flattenLogData.stream && (
<LogGeneralField fieldKey="stream" fieldValue={flattenLogData.stream} />
)}
<LogGeneralField
fieldKey="timestamp"
fieldValue={dayjs((flattenLogData.timestamp as never) / 1e6).format()}
/>
</>
</LogContainer>
<div>
{'{'}
<LogContainer>
<>
<LogGeneralField fieldKey="log" fieldValue={flattenLogData.body} />
{flattenLogData.stream && (
<LogGeneralField fieldKey="stream" fieldValue={flattenLogData.stream} />
)}
<LogGeneralField
fieldKey="timestamp"
fieldValue={dayjs((flattenLogData.timestamp as never) / 1e6).format()}
/>
</>
</LogContainer>
{'}'}
</div>
<div>
{map(selected, (field) =>
{updatedSelecedFields.map((field) =>
isValidLogField(flattenLogData[field.name] as never) ? (
<LogSelectedField
key={field.name}
@@ -140,19 +143,19 @@ function ListLogView({ logData }: ListLogViewProps): JSX.Element {
size="small"
type="text"
onClick={handleDetailedView}
style={{ color: blue[5], padding: 0, margin: 0 }}
style={{ color: blue[5] }}
icon={<ExpandAltOutlined />}
>
{' '}
<ExpandAltOutlined /> View Details
View Details
</Button>
<Button
size="small"
type="text"
onClick={handleCopyJSON}
style={{ padding: 0, margin: 0, color: grey[1] }}
style={{ color: grey[1] }}
icon={<CopyFilled />}
>
{' '}
<CopyFilled /> Copy JSON
Copy JSON
</Button>
</Row>
</Container>

View File

@@ -33,3 +33,17 @@ export const TextContainer = styled.div`
export const LogContainer = styled.div`
margin-left: 0.5rem;
`;
export const LogText = styled.div`
display: inline-block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
`;
export const SelectedLog = styled.div`
display: flex;
width: 100%;
overflow: hidden;
`;

View File

@@ -1,5 +1,3 @@
export const rawLineStyle: React.CSSProperties = {
marginBottom: 0,
fontFamily: "'Fira Code', monospace",
fontWeight: 300,
};
import { CSSProperties } from 'react';
export const rawLineStyle: CSSProperties = {};

View File

@@ -1,15 +1,22 @@
import { ExpandAltOutlined } from '@ant-design/icons';
import { Typography } from 'antd';
// const Convert = require('ansi-to-html');
import Convert from 'ansi-to-html';
import dayjs from 'dayjs';
import dompurify from 'dompurify';
// hooks
import { useIsDarkMode } from 'hooks/useDarkMode';
import React, { useCallback, useMemo } from 'react';
import { useCallback, useMemo } from 'react';
// interfaces
import { ILog } from 'types/api/logs/log';
import { rawLineStyle } from './config';
// styles
import { ExpandIconWrapper, RawLogViewContainer } from './styles';
import {
ExpandIconWrapper,
RawLogContent,
RawLogViewContainer,
} from './styles';
const convert = new Convert();
interface RawLogViewProps {
data: ILog;
@@ -27,20 +34,28 @@ function RawLogView(props: RawLogViewProps): JSX.Element {
[data.timestamp, data.body],
);
const ellipsis = useMemo(() => ({ rows: linesPerRow }), [linesPerRow]);
const handleClickExpand = useCallback(() => {
onClickExpand(data);
}, [onClickExpand, data]);
const html = useMemo(
() => ({
__html: convert.toHtml(dompurify.sanitize(text)),
}),
[text],
);
return (
<RawLogViewContainer wrap={false} align="middle" $isDarkMode={isDarkMode}>
<ExpandIconWrapper flex="30px" onClick={handleClickExpand}>
<RawLogViewContainer
onClick={handleClickExpand}
wrap={false}
align="middle"
$isDarkMode={isDarkMode}
>
<ExpandIconWrapper flex="30px">
<ExpandAltOutlined />
</ExpandIconWrapper>
<Typography.Paragraph style={rawLineStyle} ellipsis={ellipsis}>
{text}
</Typography.Paragraph>
<RawLogContent linesPerRow={linesPerRow} dangerouslySetInnerHTML={html} />
</RawLogViewContainer>
);
}

View File

@@ -22,3 +22,25 @@ export const ExpandIconWrapper = styled(Col)`
cursor: pointer;
font-size: 12px;
`;
interface RawLogContentProps {
linesPerRow: number;
}
export const RawLogContent = styled.div<RawLogContentProps>`
margin-bottom: 0;
font-family: Fira Code, monospace;
font-weight: 300;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: ${(props): number => props.linesPerRow};
line-clamp: ${(props): number => props.linesPerRow};
-webkit-box-orient: vertical;
font-size: 1rem;
line-height: 2rem;
cursor: pointer;
`;

View File

@@ -1,12 +1,18 @@
import { TableProps } from 'antd';
import { CSSProperties } from 'react';
export const defaultCellStyle: React.CSSProperties = {
export const defaultCellStyle: CSSProperties = {
paddingTop: 4,
paddingBottom: 6,
paddingRight: 8,
paddingLeft: 8,
};
export const defaultTableStyle: CSSProperties = {
minWidth: '40rem',
maxWidth: '40rem',
};
export const tableScroll: TableProps<Record<string, unknown>>['scroll'] = {
x: true,
};

View File

@@ -1,10 +1,12 @@
import { ExpandAltOutlined } from '@ant-design/icons';
import Convert from 'ansi-to-html';
import { Table, Typography } from 'antd';
import { ColumnsType, ColumnType } from 'antd/es/table';
import dayjs from 'dayjs';
import dompurify from 'dompurify';
// utils
import { FlatLogData } from 'lib/logs/flatLogData';
import React, { useMemo } from 'react';
import { useMemo } from 'react';
import { IField } from 'types/api/logs/fields';
// interfaces
import { ILog } from 'types/api/logs/log';
@@ -12,7 +14,8 @@ import { ILog } from 'types/api/logs/log';
// styles
import { ExpandIconWrapper } from '../RawLogView/styles';
// config
import { defaultCellStyle, tableScroll } from './config';
import { defaultCellStyle, defaultTableStyle, tableScroll } from './config';
import { TableBodyContent } from './styles';
type ColumnTypeRender<T = unknown> = ReturnType<
NonNullable<ColumnType<T>['render']>
@@ -25,6 +28,8 @@ type LogsTableViewProps = {
onClickExpand: (log: ILog) => void;
};
const convert = new Convert();
function LogsTableView(props: LogsTableViewProps): JSX.Element {
const { logs, fields, linesPerRow, onClickExpand } = props;
@@ -33,8 +38,9 @@ function LogsTableView(props: LogsTableViewProps): JSX.Element {
]);
const columns: ColumnsType<Record<string, unknown>> = useMemo(() => {
const fieldColumns: ColumnsType<Record<string, unknown>> = fields.map(
({ name }) => ({
const fieldColumns: ColumnsType<Record<string, unknown>> = fields
.filter((e) => e.name !== 'id')
.map(({ name }) => ({
title: name,
dataIndex: name,
key: name,
@@ -48,8 +54,7 @@ function LogsTableView(props: LogsTableViewProps): JSX.Element {
</Typography.Paragraph>
),
}),
}),
);
}));
return [
{
@@ -73,26 +78,42 @@ function LogsTableView(props: LogsTableViewProps): JSX.Element {
}),
},
{
title: 'Timestamp',
title: 'timestamp',
dataIndex: 'timestamp',
key: 'timestamp',
// https://github.com/ant-design/ant-design/discussions/36886
render: (field): ColumnTypeRender<Record<string, unknown>> => {
const date = dayjs(field / 1e6).format();
return {
props: {
style: defaultCellStyle,
},
children: <span>{date}</span>,
children: <Typography.Paragraph ellipsis>{date}</Typography.Paragraph>,
};
},
},
...fieldColumns,
{
title: 'body',
dataIndex: 'body',
key: 'body',
render: (field): ColumnTypeRender<Record<string, unknown>> => ({
props: {
style: defaultTableStyle,
},
children: (
<TableBodyContent
dangerouslySetInnerHTML={{
__html: convert.toHtml(dompurify.sanitize(field)),
}}
linesPerRow={linesPerRow}
/>
),
}),
},
];
}, [fields, linesPerRow, onClickExpand]);
return (
<Table
size="small"
columns={columns}
dataSource={flattenLogData}
pagination={false}

View File

@@ -0,0 +1,19 @@
import styled from 'styled-components';
interface TableBodyContentProps {
linesPerRow: number;
}
export const TableBodyContent = styled.div<TableBodyContentProps>`
margin-bottom: 0;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: ${(props): number => props.linesPerRow};
line-clamp: ${(props): number => props.linesPerRow};
-webkit-box-orient: vertical;
font-size: 0.875rem;
line-height: 2rem;
`;

View File

@@ -0,0 +1,8 @@
import { Button } from 'antd';
import styled from 'styled-components';
export const ButtonContainer = styled(Button)`
&&& {
padding-left: 0;
}
`;

View File

@@ -0,0 +1,47 @@
import { render, screen } from '@testing-library/react';
import MessageTip from './index';
describe('MessageTip', () => {
it('should not render when show prop is false', () => {
render(
<MessageTip
show={false}
message="Test Message"
action={<button type="button">Close</button>}
/>,
);
const messageTip = screen.queryByRole('alert');
expect(messageTip).toBeNull();
});
it('should render with the provided message and action', () => {
const message = 'Test Message';
const action = <button type="button">Close</button>;
render(<MessageTip show message={message} action={action} />);
const messageTip = screen.getByRole('alert');
const messageText = screen.getByText(message);
const actionButton = screen.getByRole('button', { name: 'Close' });
expect(messageTip).toBeInTheDocument();
expect(messageText).toBeInTheDocument();
expect(actionButton).toBeInTheDocument();
});
// taken from antd docs
// https://github.com/ant-design/ant-design/blob/master/components/alert/__tests__/index.test.tsx
it('custom action', () => {
const { container } = render(
<MessageTip
show
message="Success Tips"
action={<button type="button">Close</button>}
/>,
);
expect(container.firstChild).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,54 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`MessageTip custom action 1`] = `
.c0 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
<div
class="ant-alert ant-alert-info ant-alert-with-description c0 css-dev-only-do-not-override-1i536d8"
data-show="true"
role="alert"
>
<span
aria-label="info-circle"
class="anticon anticon-info-circle ant-alert-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="info-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm32 664c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V456c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272zm-32-344a48.01 48.01 0 010-96 48.01 48.01 0 010 96z"
/>
</svg>
</span>
<div
class="ant-alert-content"
>
<div
class="ant-alert-description"
>
Success Tips
</div>
</div>
<div
class="ant-alert-action"
>
<button
type="button"
>
Close
</button>
</div>
</div>
`;

View File

@@ -1,11 +1,11 @@
import React from 'react';
import { ReactNode } from 'react';
import { StyledAlert } from './styles';
interface MessageTipProps {
show?: boolean;
message: React.ReactNode | string;
action: React.ReactNode | undefined;
message: ReactNode | string;
action: ReactNode | undefined;
}
function MessageTip({

View File

@@ -1,5 +1,5 @@
import { Modal, ModalProps as Props } from 'antd';
import React, { ReactElement } from 'react';
import { ReactElement } from 'react';
function CustomModal({
title,

View File

@@ -1,5 +1,4 @@
import { render } from '@testing-library/react';
import React from 'react';
import { Provider } from 'react-redux';
import { MemoryRouter } from 'react-router-dom';
import store from 'store';

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