Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
ComfyUI
Commits
cb25b883
Commit
cb25b883
authored
Aug 04, 2023
by
comfyanonymous
Browse files
Merge branch 'logging' of
https://github.com/pythongosssss/ComfyUI
parents
1ce0d8ad
b2ea0cbd
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
387 additions
and
0 deletions
+387
-0
server.py
server.py
+5
-0
web/scripts/api.js
web/scripts/api.js
+9
-0
web/scripts/app.js
web/scripts/app.js
+6
-0
web/scripts/logging.js
web/scripts/logging.js
+367
-0
No files found.
server.py
View file @
cb25b883
...
@@ -345,6 +345,11 @@ class PromptServer():
...
@@ -345,6 +345,11 @@ class PromptServer():
vram_total
,
torch_vram_total
=
comfy
.
model_management
.
get_total_memory
(
device
,
torch_total_too
=
True
)
vram_total
,
torch_vram_total
=
comfy
.
model_management
.
get_total_memory
(
device
,
torch_total_too
=
True
)
vram_free
,
torch_vram_free
=
comfy
.
model_management
.
get_free_memory
(
device
,
torch_free_too
=
True
)
vram_free
,
torch_vram_free
=
comfy
.
model_management
.
get_free_memory
(
device
,
torch_free_too
=
True
)
system_stats
=
{
system_stats
=
{
"system"
:
{
"os"
:
os
.
name
,
"python_version"
:
sys
.
version
,
"embedded_python"
:
os
.
path
.
split
(
os
.
path
.
split
(
sys
.
executable
)[
0
])[
1
]
==
"python_embeded"
},
"devices"
:
[
"devices"
:
[
{
{
"name"
:
device_name
,
"name"
:
device_name
,
...
...
web/scripts/api.js
View file @
cb25b883
...
@@ -264,6 +264,15 @@ class ComfyApi extends EventTarget {
...
@@ -264,6 +264,15 @@ class ComfyApi extends EventTarget {
}
}
}
}
/**
* Gets system & device stats
* @returns System stats such as python version, OS, per device info
*/
async
getSystemStats
()
{
const
res
=
await
this
.
fetchApi
(
"
/system_stats
"
);
return
await
res
.
json
();
}
/**
/**
* Sends a POST request to the API
* Sends a POST request to the API
* @param {*} type The endpoint to post to
* @param {*} type The endpoint to post to
...
...
web/scripts/app.js
View file @
cb25b883
import
{
ComfyLogging
}
from
"
./logging.js
"
;
import
{
ComfyWidgets
}
from
"
./widgets.js
"
;
import
{
ComfyWidgets
}
from
"
./widgets.js
"
;
import
{
ComfyUI
,
$el
}
from
"
./ui.js
"
;
import
{
ComfyUI
,
$el
}
from
"
./ui.js
"
;
import
{
api
}
from
"
./api.js
"
;
import
{
api
}
from
"
./api.js
"
;
...
@@ -31,6 +32,7 @@ export class ComfyApp {
...
@@ -31,6 +32,7 @@ export class ComfyApp {
constructor
()
{
constructor
()
{
this
.
ui
=
new
ComfyUI
(
this
);
this
.
ui
=
new
ComfyUI
(
this
);
this
.
logging
=
new
ComfyLogging
(
this
);
/**
/**
* List of extensions that are registered with the app
* List of extensions that are registered with the app
...
@@ -1023,6 +1025,7 @@ export class ComfyApp {
...
@@ -1023,6 +1025,7 @@ export class ComfyApp {
*/
*/
async
#
loadExtensions
()
{
async
#
loadExtensions
()
{
const
extensions
=
await
api
.
getExtensions
();
const
extensions
=
await
api
.
getExtensions
();
this
.
logging
.
addEntry
(
"
Comfy.App
"
,
"
debug
"
,
{
Extensions
:
extensions
});
for
(
const
ext
of
extensions
)
{
for
(
const
ext
of
extensions
)
{
try
{
try
{
await
import
(
api
.
apiURL
(
ext
));
await
import
(
api
.
apiURL
(
ext
));
...
@@ -1306,6 +1309,9 @@ export class ComfyApp {
...
@@ -1306,6 +1309,9 @@ export class ComfyApp {
(
t
)
=>
`<li>
${
t
}
</li>`
(
t
)
=>
`<li>
${
t
}
</li>`
).
join
(
""
)}
</ul>Nodes that have failed to load will show as red on the graph.`
).
join
(
""
)}
</ul>Nodes that have failed to load will show as red on the graph.`
);
);
this
.
logging
.
addEntry
(
"
Comfy.App
"
,
"
warn
"
,
{
MissingNodes
:
nodes
,
});
}
}
}
}
...
...
web/scripts/logging.js
0 → 100644
View file @
cb25b883
import
{
$el
,
ComfyDialog
}
from
"
./ui.js
"
;
import
{
api
}
from
"
./api.js
"
;
$el
(
"
style
"
,
{
textContent
:
`
.comfy-logging-logs {
display: grid;
color: var(--fg-color);
white-space: pre-wrap;
}
.comfy-logging-log {
display: contents;
}
.comfy-logging-title {
background: var(--tr-even-bg-color);
font-weight: bold;
margin-bottom: 5px;
text-align: center;
}
.comfy-logging-log div {
background: var(--row-bg);
padding: 5px;
}
`
,
parent
:
document
.
body
,
});
// Stringify function supporting max depth and removal of circular references
// https://stackoverflow.com/a/57193345
function
stringify
(
val
,
depth
,
replacer
,
space
,
onGetObjID
)
{
depth
=
isNaN
(
+
depth
)
?
1
:
depth
;
var
recursMap
=
new
WeakMap
();
function
_build
(
val
,
depth
,
o
,
a
,
r
)
{
// (JSON.stringify() has it's own rules, which we respect here by using it for property iteration)
return
!
val
||
typeof
val
!=
"
object
"
?
val
:
((
r
=
recursMap
.
has
(
val
)),
recursMap
.
set
(
val
,
true
),
(
a
=
Array
.
isArray
(
val
)),
r
?
(
o
=
(
onGetObjID
&&
onGetObjID
(
val
))
||
null
)
:
JSON
.
stringify
(
val
,
function
(
k
,
v
)
{
if
(
a
||
depth
>
0
)
{
if
(
replacer
)
v
=
replacer
(
k
,
v
);
if
(
!
k
)
return
(
a
=
Array
.
isArray
(
v
)),
(
val
=
v
);
!
o
&&
(
o
=
a
?
[]
:
{});
o
[
k
]
=
_build
(
v
,
a
?
depth
:
depth
-
1
);
}
}),
o
===
void
0
?
(
a
?
[]
:
{})
:
o
);
}
return
JSON
.
stringify
(
_build
(
val
,
depth
),
null
,
space
);
}
const
jsonReplacer
=
(
k
,
v
,
ui
)
=>
{
if
(
v
instanceof
Array
&&
v
.
length
===
1
)
{
v
=
v
[
0
];
}
if
(
v
instanceof
Date
)
{
v
=
v
.
toISOString
();
if
(
ui
)
{
v
=
v
.
split
(
"
T
"
)[
1
];
}
}
if
(
v
instanceof
Error
)
{
let
err
=
""
;
if
(
v
.
name
)
err
+=
v
.
name
+
"
\n
"
;
if
(
v
.
message
)
err
+=
v
.
message
+
"
\n
"
;
if
(
v
.
stack
)
err
+=
v
.
stack
+
"
\n
"
;
if
(
!
err
)
{
err
=
v
.
toString
();
}
v
=
err
;
}
return
v
;
};
const
fileInput
=
$el
(
"
input
"
,
{
type
:
"
file
"
,
accept
:
"
.json
"
,
style
:
{
display
:
"
none
"
},
parent
:
document
.
body
,
});
class
ComfyLoggingDialog
extends
ComfyDialog
{
constructor
(
logging
)
{
super
();
this
.
logging
=
logging
;
}
clear
()
{
this
.
logging
.
clear
();
this
.
show
();
}
export
()
{
const
blob
=
new
Blob
([
stringify
([...
this
.
logging
.
entries
],
20
,
jsonReplacer
,
"
\t
"
)],
{
type
:
"
application/json
"
,
});
const
url
=
URL
.
createObjectURL
(
blob
);
const
a
=
$el
(
"
a
"
,
{
href
:
url
,
download
:
`comfyui-logs-
${
Date
.
now
()}
.json`
,
style
:
{
display
:
"
none
"
},
parent
:
document
.
body
,
});
a
.
click
();
setTimeout
(
function
()
{
a
.
remove
();
window
.
URL
.
revokeObjectURL
(
url
);
},
0
);
}
import
()
{
fileInput
.
onchange
=
()
=>
{
const
reader
=
new
FileReader
();
reader
.
onload
=
()
=>
{
fileInput
.
remove
();
try
{
const
obj
=
JSON
.
parse
(
reader
.
result
);
if
(
obj
instanceof
Array
)
{
this
.
show
(
obj
);
}
else
{
throw
new
Error
(
"
Invalid file selected.
"
);
}
}
catch
(
error
)
{
alert
(
"
Unable to load logs:
"
+
error
.
message
);
}
};
reader
.
readAsText
(
fileInput
.
files
[
0
]);
};
fileInput
.
click
();
}
createButtons
()
{
return
[
$el
(
"
button
"
,
{
type
:
"
button
"
,
textContent
:
"
Clear
"
,
onclick
:
()
=>
this
.
clear
(),
}),
$el
(
"
button
"
,
{
type
:
"
button
"
,
textContent
:
"
Export logs...
"
,
onclick
:
()
=>
this
.
export
(),
}),
$el
(
"
button
"
,
{
type
:
"
button
"
,
textContent
:
"
View exported logs...
"
,
onclick
:
()
=>
this
.
import
(),
}),
...
super
.
createButtons
(),
];
}
getTypeColor
(
type
)
{
switch
(
type
)
{
case
"
error
"
:
return
"
red
"
;
case
"
warn
"
:
return
"
orange
"
;
case
"
debug
"
:
return
"
dodgerblue
"
;
}
}
show
(
entries
)
{
if
(
!
entries
)
entries
=
this
.
logging
.
entries
;
this
.
element
.
style
.
width
=
"
100%
"
;
const
cols
=
{
source
:
"
Source
"
,
type
:
"
Type
"
,
timestamp
:
"
Timestamp
"
,
message
:
"
Message
"
,
};
const
keys
=
Object
.
keys
(
cols
);
const
headers
=
Object
.
values
(
cols
).
map
((
title
)
=>
$el
(
"
div.comfy-logging-title
"
,
{
textContent
:
title
,
})
);
const
rows
=
entries
.
map
((
entry
,
i
)
=>
{
return
$el
(
"
div.comfy-logging-log
"
,
{
$
:
(
el
)
=>
el
.
style
.
setProperty
(
"
--row-bg
"
,
`var(--tr-
${
i
%
2
?
"
even
"
:
"
odd
"
}
-bg-color)`
),
},
keys
.
map
((
key
)
=>
{
let
v
=
entry
[
key
];
let
color
;
if
(
key
===
"
type
"
)
{
color
=
this
.
getTypeColor
(
v
);
}
else
{
v
=
jsonReplacer
(
key
,
v
,
true
);
if
(
typeof
v
===
"
object
"
)
{
v
=
stringify
(
v
,
5
,
jsonReplacer
,
"
"
);
}
}
return
$el
(
"
div
"
,
{
style
:
{
color
,
},
textContent
:
v
,
});
})
);
});
const
grid
=
$el
(
"
div.comfy-logging-logs
"
,
{
style
:
{
gridTemplateColumns
:
`repeat(
${
headers
.
length
}
, 1fr)`
,
},
},
[...
headers
,
...
rows
]
);
const
els
=
[
grid
];
if
(
!
this
.
logging
.
enabled
)
{
els
.
unshift
(
$el
(
"
h3
"
,
{
style
:
{
textAlign
:
"
center
"
},
textContent
:
"
Logging is disabled
"
,
})
);
}
super
.
show
(
$el
(
"
div
"
,
els
));
}
}
export
class
ComfyLogging
{
/**
* @type Array<{ source: string, type: string, timestamp: Date, message: any }>
*/
entries
=
[];
#
enabled
;
#
console
=
{};
get
enabled
()
{
return
this
.
#
enabled
;
}
set
enabled
(
value
)
{
if
(
value
===
this
.
#
enabled
)
return
;
if
(
value
)
{
this
.
patchConsole
();
}
else
{
this
.
unpatchConsole
();
}
this
.
#
enabled
=
value
;
}
constructor
(
app
)
{
this
.
app
=
app
;
this
.
dialog
=
new
ComfyLoggingDialog
(
this
);
this
.
addSetting
();
this
.
catchUnhandled
();
this
.
addInitData
();
}
addSetting
()
{
const
settingId
=
"
Comfy.Logging.Enabled
"
;
const
htmlSettingId
=
settingId
.
replaceAll
(
"
.
"
,
"
-
"
);
const
setting
=
this
.
app
.
ui
.
settings
.
addSetting
({
id
:
settingId
,
name
:
settingId
,
defaultValue
:
true
,
type
:
(
name
,
setter
,
value
)
=>
{
return
$el
(
"
tr
"
,
[
$el
(
"
td
"
,
[
$el
(
"
label
"
,
{
textContent
:
"
Logging
"
,
for
:
htmlSettingId
,
}),
]),
$el
(
"
td
"
,
[
$el
(
"
input
"
,
{
id
:
htmlSettingId
,
type
:
"
checkbox
"
,
checked
:
value
,
onchange
:
(
event
)
=>
{
setter
((
this
.
enabled
=
event
.
target
.
checked
));
},
}),
$el
(
"
button
"
,
{
textContent
:
"
View Logs
"
,
onclick
:
()
=>
{
this
.
app
.
ui
.
settings
.
element
.
close
();
this
.
dialog
.
show
();
},
style
:
{
fontSize
:
"
14px
"
,
display
:
"
block
"
,
marginTop
:
"
5px
"
,
},
}),
]),
]);
},
});
this
.
enabled
=
setting
.
value
;
}
patchConsole
()
{
// Capture common console outputs
const
self
=
this
;
for
(
const
type
of
[
"
log
"
,
"
warn
"
,
"
error
"
,
"
debug
"
])
{
const
orig
=
console
[
type
];
this
.
#
console
[
type
]
=
orig
;
console
[
type
]
=
function
()
{
orig
.
apply
(
console
,
arguments
);
self
.
addEntry
(
"
console
"
,
type
,
...
arguments
);
};
}
}
unpatchConsole
()
{
// Restore original console functions
for
(
const
type
of
Object
.
keys
(
this
.
#
console
))
{
console
[
type
]
=
this
.
#
console
[
type
];
}
this
.
#
console
=
{};
}
catchUnhandled
()
{
// Capture uncaught errors
window
.
addEventListener
(
"
error
"
,
(
e
)
=>
{
this
.
addEntry
(
"
window
"
,
"
error
"
,
e
.
error
??
"
Unknown error
"
);
return
false
;
});
window
.
addEventListener
(
"
unhandledrejection
"
,
(
e
)
=>
{
this
.
addEntry
(
"
unhandledrejection
"
,
"
error
"
,
e
.
reason
??
"
Unknown error
"
);
});
}
clear
()
{
this
.
entries
=
[];
}
addEntry
(
source
,
type
,
...
args
)
{
if
(
this
.
enabled
)
{
this
.
entries
.
push
({
source
,
type
,
timestamp
:
new
Date
(),
message
:
args
,
});
}
}
log
(
source
,
...
args
)
{
this
.
addEntry
(
source
,
"
log
"
,
...
args
);
}
async
addInitData
()
{
if
(
!
this
.
enabled
)
return
;
const
source
=
"
ComfyUI.Logging
"
;
this
.
addEntry
(
source
,
"
debug
"
,
{
UserAgent
:
navigator
.
userAgent
});
const
systemStats
=
await
api
.
getSystemStats
();
this
.
addEntry
(
source
,
"
debug
"
,
systemStats
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment