Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
701ccb5d
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
701ccb5d
编写于
11月 28, 2018
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
adjust wording, add report issue from silent perf notification
上级
e5094daf
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
83 addition
and
50 deletion
+83
-50
src/vs/workbench/parts/extensions/electron-browser/extensionsAutoProfiler.ts
...rts/extensions/electron-browser/extensionsAutoProfiler.ts
+70
-47
src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts
...ts/extensions/electron-browser/runtimeExtensionsEditor.ts
+13
-3
未找到文件。
src/vs/workbench/parts/extensions/electron-browser/extensionsAutoProfiler.ts
浏览文件 @
701ccb5d
...
...
@@ -13,12 +13,13 @@ import { onUnexpectedError } from 'vs/base/common/errors';
import
{
tmpdir
}
from
'
os
'
;
import
{
join
}
from
'
path
'
;
import
{
writeFile
}
from
'
vs/base/node/pfs
'
;
import
{
IExtensionHostProfileService
}
from
'
vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor
'
;
import
{
IExtensionHostProfileService
,
ReportExtensionIssueAction
}
from
'
vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor
'
;
import
{
INotificationService
,
Severity
}
from
'
vs/platform/notification/common/notification
'
;
import
{
localize
}
from
'
vs/nls
'
;
import
{
IEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
RuntimeExtensionsInput
}
from
'
vs/workbench/services/extensions/electron-browser/runtimeExtensionsInput
'
;
import
{
generateUuid
}
from
'
vs/base/common/uuid
'
;
import
{
IExtensionsWorkbenchService
}
from
'
vs/workbench/parts/extensions/common/extensions
'
;
export
class
ExtensionsAutoProfiler
extends
Disposable
implements
IWorkbenchContribution
{
...
...
@@ -27,6 +28,7 @@ export class ExtensionsAutoProfiler extends Disposable implements IWorkbenchCont
constructor
(
@
IExtensionService
private
_extensionService
:
IExtensionService
,
@
IExtensionHostProfileService
private
readonly
_extensionProfileService
:
IExtensionHostProfileService
,
@
IExtensionsWorkbenchService
private
readonly
_anotherExtensionService
:
IExtensionsWorkbenchService
,
@
ITelemetryService
private
readonly
_telemetryService
:
ITelemetryService
,
@
ILogService
private
readonly
_logService
:
ILogService
,
@
INotificationService
private
readonly
_notificationService
:
INotificationService
,
...
...
@@ -80,7 +82,7 @@ export class ExtensionsAutoProfiler extends Disposable implements IWorkbenchCont
}
}
private
_processCpuProfile
(
profile
:
IExtensionHostProfile
)
{
private
async
_processCpuProfile
(
profile
:
IExtensionHostProfile
)
{
interface
NamedSlice
{
id
:
string
;
...
...
@@ -108,7 +110,6 @@ export class ExtensionsAutoProfiler extends Disposable implements IWorkbenchCont
}
data
=
data
.
slice
(
0
,
anchor
+
1
);
const
id
=
generateUuid
();
const
duration
=
profile
.
endTime
-
profile
.
startTime
;
const
percentage
=
duration
/
100
;
let
top
:
NamedSlice
|
undefined
;
...
...
@@ -123,55 +124,77 @@ export class ExtensionsAutoProfiler extends Disposable implements IWorkbenchCont
return
;
}
this
.
_extensionService
.
getExtension
(
top
.
id
).
then
(
async
extension
=>
{
if
(
!
extension
)
{
return
;
}
const
extension
=
await
this
.
_extensionService
.
getExtension
(
top
.
id
);
if
(
!
extension
)
{
// not an extension => idle, gc, self?
return
;
}
// add to running extensions view
this
.
_extensionProfileService
.
setUnresponsiveProfile
(
extension
.
id
,
profile
);
// user-facing message when very bad...
const
prompt
=
top
.
percentage
>=
99
&&
top
.
total
>=
5
e6
;
if
(
prompt
)
{
this
.
_notificationService
.
prompt
(
Severity
.
Info
,
localize
(
'
unresponsive-exthost
'
,
"
Extension '{0}' froze the extension host for more than {1} seconds.
"
,
extension
.
displayName
||
extension
.
name
,
Math
.
round
(
duration
/
1
e6
)),
[{
label
:
localize
(
'
show
'
,
'
Show Extensions
'
),
run
:
()
=>
{
this
.
_editorService
.
openEditor
(
new
RuntimeExtensionsInput
());
/* __GDPR__
"exthostunresponsive-more" : {
"id" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
}
*/
this
.
_telemetryService
.
publicLog
(
'
exthostunresponsive-more
'
,
{
id
});
}
}],
{
silent
:
true
}
);
// add to running extensions view
this
.
_extensionProfileService
.
setUnresponsiveProfile
(
extension
.
id
,
profile
);
// print message to log
const
path
=
join
(
tmpdir
(),
`exthost-
${
Math
.
random
().
toString
(
16
).
slice
(
2
,
8
)}
.cpuprofile`
);
await
writeFile
(
path
,
JSON
.
stringify
(
profile
.
data
));
this
.
_logService
.
warn
(
`UNRESPONSIVE extension host, '
${
top
.
id
}
' took
${
top
!
.
percentage
}
% of
${
duration
/
1
e3
}
ms, saved PROFILE here: '
${
path
}
'`
,
data
);
// send telemetry
const
id
=
generateUuid
();
/* __GDPR__
"exthostunresponsive" : {
"id" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
"duration" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"data": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
}
*/
this
.
_telemetryService
.
publicLog
(
'
exthostunresponsive
'
,
{
id
,
duration
,
data
,
});
const
path
=
join
(
tmpdir
(),
`exthost-
${
Math
.
random
().
toString
(
16
).
slice
(
2
,
8
)}
.cpuprofile`
);
await
writeFile
(
path
,
JSON
.
stringify
(
profile
.
data
));
// prompt: when really slow/greedy
if
(
!
(
top
.
percentage
>=
99
&&
top
.
total
>=
5
e6
))
{
return
;
}
this
.
_logService
.
warn
(
`UNRESPONSIVE extension host, '
${
top
.
id
}
' took
${
top
!
.
percentage
}
% of
${
duration
/
1
e3
}
ms, saved PROFILE here: '
${
path
}
'`
,
data
);
// prompt: only when you can file an issue
const
reportAction
=
new
ReportExtensionIssueAction
({
marketplaceInfo
:
this
.
_anotherExtensionService
.
local
.
filter
(
value
=>
value
.
id
===
extension
.
id
)[
0
],
description
:
extension
,
unresponsiveProfile
:
profile
,
status
:
undefined
,
});
if
(
!
reportAction
.
enabled
)
{
return
;
}
/* __GDPR__
"exthostunresponsive" : {
"id" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
"duration" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"data": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
"prompt" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
// user-facing message when very bad...
this
.
_notificationService
.
prompt
(
Severity
.
Info
,
localize
(
'
unresponsive-exthost
'
,
"
The extension '{0}' took a very long time to complete its last task and it has prevented other extensions from running.
"
,
extension
.
displayName
||
extension
.
name
),
[{
label
:
localize
(
'
show
'
,
'
Show Extensions
'
),
run
:
()
=>
this
.
_editorService
.
openEditor
(
new
RuntimeExtensionsInput
())
},
{
label
:
localize
(
'
report
'
,
"
Report Issue
"
),
run
:
()
=>
{
/* __GDPR__
"exthostunresponsive/report" : {
"id" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
}
*/
this
.
_telemetryService
.
publicLog
(
'
exthostunresponsive/report
'
,
{
id
});
return
reportAction
.
run
();
}
*/
this
.
_telemetryService
.
publicLog
(
'
exthostunresponsive
'
,
{
id
,
duration
,
data
,
prompt
});
});
}],
{
silent
:
true
}
);
}
}
src/vs/workbench/parts/extensions/electron-browser/runtimeExtensionsEditor.ts
浏览文件 @
701ccb5d
...
...
@@ -463,14 +463,19 @@ export class ShowRuntimeExtensionsAction extends Action {
}
}
class
ReportExtensionIssueAction
extends
Action
{
export
class
ReportExtensionIssueAction
extends
Action
{
private
static
readonly
_id
=
'
workbench.extensions.action.reportExtensionIssue
'
;
private
static
_label
=
nls
.
localize
(
'
reportExtensionIssue
'
,
"
Report Issue
"
);
private
readonly
_url
:
string
;
constructor
(
extension
:
IRuntimeExtension
)
{
constructor
(
extension
:
{
description
:
IExtensionDescription
;
marketplaceInfo
:
IExtension
;
status
:
IExtensionsStatus
;
unresponsiveProfile
?:
IExtensionHostProfile
})
{
super
(
ReportExtensionIssueAction
.
_id
,
ReportExtensionIssueAction
.
_label
,
'
extension-action report-issue
'
);
this
.
enabled
=
extension
.
marketplaceInfo
&&
extension
.
marketplaceInfo
.
type
===
LocalExtensionType
.
User
...
...
@@ -484,7 +489,12 @@ class ReportExtensionIssueAction extends Action {
return
Promise
.
resolve
(
null
);
}
private
static
_generateNewIssueUrl
(
extension
:
IRuntimeExtension
):
string
{
private
static
_generateNewIssueUrl
(
extension
:
{
description
:
IExtensionDescription
;
marketplaceInfo
:
IExtension
;
status
:
IExtensionsStatus
;
unresponsiveProfile
?:
IExtensionHostProfile
}):
string
{
let
baseUrl
=
extension
.
marketplaceInfo
&&
extension
.
marketplaceInfo
.
type
===
LocalExtensionType
.
User
&&
extension
.
description
.
repository
?
extension
.
description
.
repository
.
url
:
undefined
;
if
(
!!
baseUrl
)
{
baseUrl
=
`
${
baseUrl
.
indexOf
(
'
.git
'
)
!==
-
1
?
baseUrl
.
substr
(
0
,
baseUrl
.
length
-
4
)
:
baseUrl
}
/issues/new/`
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录