continuous integration - significado - Salida de la consola Jenkins no en tiempo real
jenkins significado (7)
Asegúrate de que tu script esté descargando stdout, stderr. En mi caso tuve un problema de pulido similar a lo que describes pero estaba usando Python. El siguiente código python me lo arregló:
import sys
sys.stdout.flush()
No soy un código de Ruby, pero Google revela lo siguiente:
$stdout.flush
Bastante nuevo para Jenkins y yo tenemos un problema simple pero molesto. Cuando ejecuto el trabajo (Build) en Jenkins estoy activando el comando de ruby para ejecutar mi script de prueba.
El problema es que Jenkins no muestra la salida en tiempo real desde la consola. Aquí está el registro de activación.
Building in workspace /var/lib/jenkins/workspace/foo_bar
No emails were triggered.
[foo_bar] $ /bin/sh -xe /tmp/hudson4042436272524123595.sh
+ ruby /var/lib/jenkins/test-script.rb
Básicamente se cuelga en esta salida hasta que la compilación se completa de lo que muestra la salida completa. Lo curioso es que esto no es un comportamiento constante, a veces funciona como debería. Pero la mayoría de las veces no hay salida de consola en tiempo real.
Versión de Jenkins: 1.461
Cada una de las otras respuestas es específica para un programa u otro, pero encontré una solución más general aquí:
https://unix.stackexchange.com/a/25378
Puede usar stdbuf
para alterar el comportamiento de almacenamiento en búfer de cualquier programa.
En mi caso, estaba canalizando la salida de un script de shell a través de tee
y grep
para dividir líneas en la consola o en un archivo basado en el contenido. La consola estaba colgando como lo describe OP. Esto lo resolvió:
./slowly_parse.py login.csv |tee >(grep -v LOG: > out.csv) | stdbuf -oL -eL grep LOG:
Eventualmente descubrí que podía simplemente pasar --line-buffered
a grep para obtener el mismo resultado:
./slowly_parse.py login.csv |tee >(grep -v LOG: > out.csv) | grep --line-buffered LOG:
El sistema operativo está almacenando datos de salida por naturaleza, para ahorrar CPU, y también lo hace Jenkins.
Parece que estás usando un comando de shell para ejecutar tu script de Ruby:
Sugiero ejecutar tu script de Ruby directamente a través del plugin dedicado:
(puede necesitar instalarlo)
La solución más fácil aquí es activar la sincronización del búfer a la salida. Algo sobre lo que @Craig escribió en su respuesta, pero una solución de línea que cubrirá toda la secuencia de comandos y no requiere que descargue el búfer muchas veces.
Solo escribe
STDOUT.sync = true
La lógica detrás es simple, para evitar el uso de operaciones IO muchas veces la salida se almacena en el búfer. Para desactivar este uso
STDOUT.sync = false
Esta es la solución Ruby ofc.
Las otras respuestas son correctas al decir que debe asegurarse de que la salida estándar no esté almacenada en el búfer.
La otra cosa a tener en cuenta es que Jenkins sí mismo línea por línea de almacenamiento en búfer. Si tiene un proceso de ejecución lenta que emite caracteres individuales (por ejemplo, un resumen de suite de prueba nunit que imprime a .
Para una prueba exitosa y una E
para un error) no verá nada hasta el final de la línea.
[Es cierto que mi Jenkins 1.572 se ejecuta en una caja de Windows.]
Me parece que python -u
funciona.
Por ejemplo, en el comando por lotes
python -u foo.py
Para aclarar algunas de las respuestas.
-
ruby
opython
o cualquier lenguaje de scripting sensible almacenará el resultado; esto es para minimizar el IO; escribir en el disco es lento, escribir en una consola es lento ... - por lo general, los datos se
flush()
automáticamente después de tener suficientes datos en el búfer con un manejo especial para líneas nuevas. por ejemplo, escribir una cadena sin línea nueva, luegosleep()
no escribiría nada hasta que se complete el modosleep()
(solo estoy usandosleep
como ejemplo, siéntete libre de sustituirlo con cualquier otra llamada costosa al sistema).
por ejemplo, esto esperaría 8 segundos, imprime una línea, espera 5 segundos más, imprime una segunda línea.
from time import sleep
def test():
print "ok",
time.sleep(3)
print "now",
time.sleep(5)
print "done"
time.sleep(5)
print "again"
test()
para
ruby
,STDOUT.sync = true
, activa elautoflush
; todas las escrituras enSTDOUT
son seguidas porflush()
. Esto resolvería su problema pero resultaría en más IO.STDOUT.sync = true
para
python
, puede usarpython -u
o la variable de entornoPYTHONUNBUFFERED
para hacer questdin/stdout/stout
no esté en búfer, pero hay otras soluciones que no cambianstdin
ostderr
export PYTHONUNBUFFERED=1
para
perl
, tienesautoflush
autoflush STDOUT 1;