Skip to content

Commit f1d67b1

Browse files
authored
Merge pull request #2794 from 1c-syntax/feature/sentry
Отправка исключений в Sentry
2 parents 3e796de + 976de4a commit f1d67b1

File tree

21 files changed

+1049
-2
lines changed

21 files changed

+1049
-2
lines changed

.github/workflows/sentry.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Sentry
2+
on:
3+
push:
4+
branches-ignore:
5+
- "translations_*"
6+
jobs:
7+
sentry:
8+
name: Sentry
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v2
12+
- name: Create Sentry release
13+
uses: getsentry/action-release@v1
14+
env:
15+
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
16+
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
17+
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
18+
with:
19+
environment: production

build.gradle.kts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ plugins {
2020
id("io.spring.dependency-management") version "1.0.12.RELEASE"
2121
id("io.github.1c-syntax.bslls-dev-tools") version "0.7.0"
2222
id("ru.vyarus.pom") version "2.2.1"
23+
id("com.gorylenko.gradle-git-properties") version "2.3.2"
2324
id("io.codearte.nexus-staging") version "0.30.0"
2425
}
2526

@@ -51,6 +52,12 @@ val isSnapshot = gitVersioning.gitVersionDetails.refType != GitRefType.TAG
5152

5253
val languageToolVersion = "5.6"
5354

55+
dependencyManagement {
56+
imports {
57+
mavenBom("io.sentry:sentry-bom:6.2.1")
58+
}
59+
}
60+
5461
dependencies {
5562

5663
// RUNTIME
@@ -103,6 +110,10 @@ dependencies {
103110
// SARIF serialization
104111
implementation("com.contrastsecurity", "java-sarif", "2.0")
105112

113+
// Sentry
114+
implementation("io.sentry:sentry-spring-boot-starter")
115+
implementation("io.sentry:sentry-logback")
116+
106117
// COMPILE
107118

108119
// stat analysis

docs/features/ConfigurationFile.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ BSL Language Server предоставляет возможность измен
2929
|`siteRoot`|`Строка`|Путь к корню сайта с документацией. По умолчанию параметр имеет значение `"https://1c-syntax.github.io/bsl-language-server"` |
3030
|`traceLog`|`Строка`|Для логирования всех запросов *(входящих и исходящих)* между **BSL Language Server** и **Language Client** из используемого редактора/IDE, в этом параметре можно указать путь к файлу лога. Путь можно указывать как абсолютный, так и относительный *(от корня анализируемого проекта)*, по умолчанию значение не заполнено.<br/><br/>**ВНИМАНИЕ**<br/><br/>* При запуске **BSL Language Server** перезаписывает указанный файл<br/>* Скорость взаимодействия между клиентом и сервером **ЗНАЧИТЕЛЬНО ЗАМЕДЛЯЕТСЯ**|
3131
|`configurationRoot`|`Строка`|Данный параметр предназначен для указания корневого каталога, в котором находятся файлы конфигурации 1С в каталоге проекта. Может быть полезен в случае нахождения нескольких каталогов конфигураций в одном каталоге проекта либо при сложной структуре каталога проекта. По умолчанию параметр не заполнен и `BSL Language Server` самостоятельно определяет расположение корневого каталога конфигурации|
32+
|`sendErrors`|`Строка`|Режим отправки сообщений об ошибках разработчикам BSL Language Server. Подробнее - на странице [Мониторинг и отправка ошибок](Monitoring.md). Возможные значения:<br/>* `ask` - спрашивать разрешение при каждой ошибке *(установлен по умолчанию)*. <br/>* `send` - всегда отправлять сообщения об ошибках. <br/>* `never` - никогда не отправлять сообщения об ошибках.|
3233

3334
Для облегчения составления и редактирования конфигурационного файла можно использовать следующую JSON-схему:
3435

docs/features/Monitoring.md

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
# Мониторинг и отправка ошибок
2+
3+
BSL Language Server содержит механизм отправки данных об ошибках в Sentry.
4+
5+
В качестве сервера Sentry используется публичный Sentry.io по адресу
6+
https://sentry.io/organizations/1c-syntax/projects/bsl-language-server
7+
8+
К сожалению, особенности настройки доступа к Sentry.io ограничивают возможность просмотра данных
9+
неавторизованным пользователям.
10+
11+
## Схема работы
12+
13+
В [конфигурационном файле](ConfigurationFile.md) BSL Language Server можно настроить режим отправки сообщений об ошибках.
14+
Режим отправки может принимать одно из трех значений:
15+
16+
* спросить (по умолчанию);
17+
* отправлять всегда;
18+
* никогда не отправлять.
19+
20+
Если в конфигурационном файле отсутствует настройка или она имеет значение "спросить", при возникновении ошибки
21+
подключенному language client (используемой IDE) отправляется вопрос о дальнейших действиях с ошибкой
22+
со следующими вариантами ответа:
23+
24+
* отправить эту ошибку, но спросить снова;
25+
* не отправлять эту ошибку, но спросить снова.
26+
* отправить эту ошибку и больше не спрашивать;
27+
* не отправлять эту ошибку и больше не спрашивать;
28+
29+
От ответа можно полностью отказаться (например, нажав на крестик у уведомления с вопросом).
30+
Отсутствие ответа воспринимается как "не отправлять эту ошибку, но спросить снова".
31+
32+
Сообщение об ошибке не содержит идентификационных данных пользователя или рабочей станции,
33+
за исключением генерируемого UUID сессии для связывания ошибок, возникающих в течении одного
34+
запуска BSL Language Server.
35+
36+
> Обратите внимание!
37+
38+
Если вы включите отладочные логи (настроив `logback` или используя переменные среды), содержимое логов (последние 100 записей) приложится к отправляемому событию.
39+
40+
Некоторые сообщения, пересылаемые между Language Client и BSL Language Server, содержат фрагменты исходного кода
41+
или текст файла целиком.
42+
Эти фрагменты тоже могут быть приложены к отправляемому сообщению.
43+
44+
Пример отправляемого события об ошибке:
45+
46+
??? event.json
47+
48+
```json
49+
{
50+
"event_id": "746e2e82f4c1499abcdd935bc4c26644",
51+
"project": 5790531,
52+
"release": "ae081de9d3c3496ddac1d176259365191966b0cd",
53+
"dist": null,
54+
"platform": "java",
55+
"message": "Internal error: java.lang.RuntimeException: psss",
56+
"datetime": "2022-07-14T11:07:57.875000Z",
57+
"tags": [
58+
[
59+
"environment",
60+
"production"
61+
],
62+
[
63+
"level",
64+
"error"
65+
],
66+
[
67+
"logger",
68+
"org.eclipse.lsp4j.jsonrpc.RemoteEndpoint"
69+
],
70+
[
71+
"runtime",
72+
"AdoptOpenJDK 15.0.2"
73+
],
74+
[
75+
"runtime.name",
76+
"AdoptOpenJDK"
77+
],
78+
[
79+
"release",
80+
"ae081de9d3c3496ddac1d176259365191966b0cd"
81+
],
82+
[
83+
"user",
84+
"id:49516eb9-2a0d-4a15-bd96-978b68d8d0df"
85+
],
86+
[
87+
"server.version",
88+
"feature-sentry-ae081de-DIRTY"
89+
]
90+
],
91+
"_metrics": {
92+
"bytes.ingested.event": 3289,
93+
"bytes.stored.event": 9875
94+
},
95+
"contexts": {
96+
"runtime": {
97+
"name": "AdoptOpenJDK",
98+
"version": "15.0.2",
99+
"type": "runtime"
100+
}
101+
},
102+
"culprit": "java.util.concurrent.CompletableFuture in encodeThrowable",
103+
"environment": "production",
104+
"exception": {
105+
"values": [
106+
{
107+
"type": "RuntimeException",
108+
"value": "psss",
109+
"module": "java.lang",
110+
"stacktrace": {
111+
"frames": [
112+
{
113+
"function": "run",
114+
"module": "java.util.concurrent.ForkJoinWorkerThread",
115+
"in_app": false
116+
},
117+
{
118+
"function": "runWorker",
119+
"module": "java.util.concurrent.ForkJoinPool",
120+
"in_app": false
121+
},
122+
{
123+
"function": "scan",
124+
"module": "java.util.concurrent.ForkJoinPool",
125+
"in_app": false
126+
},
127+
{
128+
"function": "topLevelExec",
129+
"module": "java.util.concurrent.ForkJoinPool$WorkQueue",
130+
"in_app": false
131+
},
132+
{
133+
"function": "doExec",
134+
"module": "java.util.concurrent.ForkJoinTask",
135+
"in_app": false
136+
},
137+
{
138+
"function": "exec",
139+
"module": "java.util.concurrent.CompletableFuture$AsyncSupply",
140+
"in_app": false
141+
},
142+
{
143+
"function": "run",
144+
"module": "java.util.concurrent.CompletableFuture$AsyncSupply",
145+
"in_app": false
146+
},
147+
{
148+
"function": "lambda$prepareCallHierarchy$8",
149+
"module": "com.github._1c_syntax.bsl.languageserver.BSLTextDocumentService",
150+
"filename": "BSLTextDocumentService.java",
151+
"abs_path": "BSLTextDocumentService.java",
152+
"lineno": 234,
153+
"in_app": true
154+
},
155+
{
156+
"function": "prepareCallHierarchy",
157+
"module": "com.github._1c_syntax.bsl.languageserver.providers.CallHierarchyProvider",
158+
"filename": "CallHierarchyProvider.java",
159+
"abs_path": "CallHierarchyProvider.java",
160+
"lineno": 62,
161+
"in_app": true
162+
}
163+
]
164+
},
165+
"thread_id": 24
166+
},
167+
{
168+
"type": "CompletionException",
169+
"value": "java.lang.RuntimeException: psss",
170+
"module": "java.util.concurrent",
171+
"stacktrace": {
172+
"frames": [
173+
{
174+
"function": "run",
175+
"module": "java.util.concurrent.ForkJoinWorkerThread",
176+
"in_app": false
177+
},
178+
{
179+
"function": "runWorker",
180+
"module": "java.util.concurrent.ForkJoinPool",
181+
"in_app": false
182+
},
183+
{
184+
"function": "scan",
185+
"module": "java.util.concurrent.ForkJoinPool",
186+
"in_app": false
187+
},
188+
{
189+
"function": "topLevelExec",
190+
"module": "java.util.concurrent.ForkJoinPool$WorkQueue",
191+
"in_app": false
192+
},
193+
{
194+
"function": "doExec",
195+
"module": "java.util.concurrent.ForkJoinTask",
196+
"in_app": false
197+
},
198+
{
199+
"function": "exec",
200+
"module": "java.util.concurrent.CompletableFuture$AsyncSupply",
201+
"in_app": false
202+
},
203+
{
204+
"function": "run",
205+
"module": "java.util.concurrent.CompletableFuture$AsyncSupply",
206+
"in_app": false
207+
},
208+
{
209+
"function": "completeThrowable",
210+
"module": "java.util.concurrent.CompletableFuture",
211+
"in_app": false
212+
},
213+
{
214+
"function": "encodeThrowable",
215+
"module": "java.util.concurrent.CompletableFuture",
216+
"in_app": false
217+
}
218+
]
219+
},
220+
"thread_id": 24
221+
}
222+
]
223+
},
224+
"extra": {
225+
"thread_name": "ForkJoinPool.commonPool-worker-19"
226+
},
227+
"fingerprint": [
228+
"{{ default }}"
229+
],
230+
"grouping_config": {
231+
"enhancements": "eJybzDRxY3J-bm5-npWRgaGlroGxrpHxBABcYgcZ",
232+
"id": "newstyle:2019-10-29"
233+
},
234+
"hashes": [
235+
"4a63b2a190b48dc2bbafb225c5140009",
236+
"cfeccf65e86c6129d81e7fd1df568ce3"
237+
],
238+
"ingest_path": [
239+
{
240+
"version": "22.6.0",
241+
"public_key": "XE7QiyuNlja9PZ7I9qJlwQotzecWrUIN91BAO7Q5R38"
242+
}
243+
],
244+
"key_id": "1646438",
245+
"level": "error",
246+
"logentry": {
247+
"formatted": "Internal error: java.lang.RuntimeException: psss"
248+
},
249+
"logger": "org.eclipse.lsp4j.jsonrpc.RemoteEndpoint",
250+
"metadata": {
251+
"display_title_with_tree_label": false,
252+
"function": "encodeThrowable",
253+
"type": "CompletionException",
254+
"value": "java.lang.RuntimeException: psss"
255+
},
256+
"nodestore_insert": 1657796884.036383,
257+
"received": 1657796882.652077,
258+
"sdk": {
259+
"name": "sentry.java.spring-boot",
260+
"version": "6.2.1",
261+
"packages": [
262+
{
263+
"name": "maven:io.sentry:sentry",
264+
"version": "6.2.1"
265+
},
266+
{
267+
"name": "maven:io.sentry:sentry-spring-boot-starter",
268+
"version": "6.2.1"
269+
}
270+
]
271+
},
272+
"timestamp": 1657796877.875,
273+
"title": "CompletionException: java.lang.RuntimeException: psss",
274+
"type": "error",
275+
"user": {
276+
"id": "49516eb9-2a0d-4a15-bd96-978b68d8d0df"
277+
},
278+
"version": "7",
279+
"location": null
280+
}
281+
```

docs/features/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44

55
* [Конфигурирование](ConfigurationFile.md)
66
* [Экранирование кода от диагностик](DiagnosticIgnorance.md)
7+
* [Мониторинг и отправка ошибок](Monitoring.md)

src/main/java/com/github/_1c_syntax/bsl/languageserver/LanguageClientHolder.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ public Optional<LanguageClient> getClient() {
5050
return Optional.ofNullable(client);
5151
}
5252

53+
/**
54+
* LanguageClient подключен.
55+
*
56+
* @return LanguageClient подключен.
57+
*/
58+
public boolean isConnected() {
59+
return client != null;
60+
}
61+
5362
public void execIfConnected(Consumer<LanguageClient> consumer) {
5463
getClient().ifPresent(consumer);
5564
}

src/main/java/com/github/_1c_syntax/bsl/languageserver/aop/AspectJConfiguration.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ public EventPublisherAspect eventPublisherAspect() {
4444
return Aspects.aspectOf(EventPublisherAspect.class);
4545
}
4646

47+
/**
48+
* @return Аспект перехвата ошибок и взаимодействия с Sentry.
49+
*/
50+
@Bean
51+
@Lazy(false)
52+
public SentryAspect sentryAspect() {
53+
return Aspects.aspectOf(SentryAspect.class);
54+
}
55+
4756
/**
4857
* @return Аспект выполнения замеров производительности.
4958
*/

0 commit comments

Comments
 (0)