SlideShare a Scribd company logo
1 of 30
Jaffle: managing processes and log
messages of multiple applications
in development environment
Masaki Yatsu
PyCon JP
Sep 18, 2018
Agenda
• Jaffle: Introducing new development tool
• Motivation
• Launching Python apps and external processes
/ Automatic job execution
• Log management in the development environment
• Managing Jaffle configurations
• Architecture of Jaffle
https://jaffle.readthedocs.io/
https://github.com/yatsu/jaffle
Jaffle
• Starts and stops multiple Python apps and external processes
• Auto task execution on detecting filesystem update (e.g. auto-testing)
• Integrated log output with filtering and replacing patterns
• A framework to integrate Python apps in a Jupyter kernel session
(described in the last section)
What is Jaffle?
Background
• There are some tools and services to manage
processes and logs in a production environment,
but there is no easy solution for a development
environment
• Recent years…
• Many applications and services must be integrated with
each other
• Each application and service outputs many and large
data
Launching Python apps and
external processes
/ Automatic job execution
Ex.1: Web dev with Tornado and React
• Launches the backend Web API server
• Launches two external processes
• “yarn start” (Frontend dev server)
• “jest” (JavaScript testing)
• On detecting .py file update
• Restart the Web API Server
• Execute pytest
• Displays integrated log messages
https://jaffle.readthedocs.io/en/latest/cookbook/tornado_spa.html
Backend development with Tornado (web framework)
Frontend development with React
Ex.2: Auto-pytest
• Executes test_*.py when it is updated
• Executes tests/foo/test_bar.py when the related
implementation foo/bar.py is updated
• Since pytest execution is always stand-by and
reloads only Python modules under the current
directory, it works fast
• Cache-clear strategy is configurable
https://jaffle.readthedocs.io/en/latest/cookbook/pytest.html
Ex.2: Auto-pytest / Config file
kernel "py_kernel" {}
app "watchdog" {
class = "jaffle.app.watchdog.WatchdogApp"
kernel = "py_kernel"
options {
handlers = [{
watch_path = "pytest_example"
patterns = ["*.py"]
ignore_directories = true
code_blocks = ["pytest.handle_watchdog_event({event})"]
}]
}
}
app "pytest" {
class = "jaffle.app.pytest.PyTestRunnerApp"
kernel = "py_kernel"
options {
args = ["-s", "-v", "—color=yes"]
auto_test = ["pytest_example/tests/test_*.py"]
auto_test_map {
"pytest_example/**/*.py" = "pytest_example/tests/{}/test_{}.py"
}
}
}
App that watches filesystem update
Executes the right-hand-side, when the left-hand-side is updated
Executes the matched test file
Defining Jupyter kernel (Python interpreter process)
Refer the variable defined in the kernel
Execute:
$ jaffle start jaffle.hcl
“jaffle.hcl” is optional:
$ jaffle start
Write jaffle.hcl as above:
Ex.3: Sphinx auto-build / Config file
kernel "py_kernel" {
pass_env = ["PATH"]
}
app "watchdog" {
class = "jaffle.app.watchdog.WatchdogApp"
kernel = "py_kernel"
options {
handlers = [{
patterns = ["*/docs/*.*"]
ignore_patterns = ["*/_build/*"]
ignore_directories = true
jobs = ["sphinx”, “refresh”]
}]
}
}
job "sphinx" {
command = "sphinx-build -M html docs docs/_build"
}
job ”refresh" {
command = ”osascript browser_refresh.scpt"
}
sphinx-build is executed automatically
when .rst files under docs/ directory
are updated
Refers the job name
Defines a job for command execution
virtualenv requires this to pass environment
variables to the kernel session
tell application "Google Chrome" to tell the active tab of its first window
reload
end tell
(for macOS)
Ex.4: Jupyter Extension Development
https://jaffle.readthedocs.io/en/latest/cookbook/jupyter_ext.html
• Restarts Jupyter Notebook Server
when .py file is updated
• Executes “jupyter nbextension
install” when .js files is updated
kernel "py_kernel" {
pass_env = ["PATH"]
}
app "watchdog" {
class = "jaffle.app.watchdog.WatchdogApp"
kernel = "py_kernel"
options {
handlers = [
{
patterns = ["*.py"]
ignore_directories = true
clear_cache = ["jupyter_myext"]
code_blocks = ["notebook.handle_watchdog_event({event})"]
},
{
patterns = ["*.js"]
ignore_directories = true
jobs = ["nbext_install"]
},
]
}
}
app "notebook" {
class = "jaffle.app.tornado.TornadoBridgeApp"
kernel = "py_kernel"
options {
app_class = "notebook.notebookapp.NotebookApp"
}
start = "notebook.start()"
}
job "nbext_install" {
command = "jupyter nbextension install jupyter_myext --user --overwrite"
}
Development of both backend (sever
extension) and frontend (nbextension)
Jupyter Notebook Server can run in the Tornado IOLoop
which Jaffle initialized
Log management in the
development environment
Problems of log management
• Hard to understand the
processing flow from multiple
log files
• Hard to find a message
because there are so many log
messages
• Hard to get an information
from a log message because
some messages are large
Log integration
Filters out unnecessary log
messages
Extracts only the necessary
information and emphasize them
with colors
Log Integration
• All messages are displayed in a single flow
• Each logger (app or process name) has its own unique
color
Log Filtering
app "pytest" {
class = "jaffle.app.pytest.PyTestRunnerApp"
kernel = "py_kernel"
logger {
suppress_regex = [
"^platform ",
"^cachedir:",
"^rootdir:",
"^plugins:",
"collecting ...",
"^collected ",
]
}
}
Filters out unnecessary messages from pytest log
Problem of large data included in a message
$ kubectl get services kubernetes -o json
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"creationTimestamp": "2018-09-06T13:09:41Z",
"labels": {
"component": "apiserver",
"provider": "kubernetes"
},
"name": "kubernetes",
"namespace": "default",
"resourceVersion": "18",
"selfLink":
"/api/v1/namespaces/default/services/kubernetes",
"uid": "1dc6394b-b1d6-11e8-859a-080027be08a0"
},
"spec": {
"clusterIP": "10.96.0.1",
"ports": [
{
"name": "https",
"port": 443,
"protocol": "TCP",
"targetPort": 8443
}
],
"sessionAffinity": "ClientIP",
"sessionAffinityConfig": {
"clientIP": {
"timeoutSeconds": 10800
}
},
"type": "ClusterIP"
},
"status": {
"loadBalancer": {}
}
}
service:
{"apiVersion":"v1","kind":"Service","metadata":{"creationTimestamp":"
2018-09-
06T13:09:41Z","labels":{"component":"apiserver","provider":"kubernete
s"},"name":"kubernetes","namespace":"default","resourceVersion":"18",
"selfLink":"/api/v1/namespaces/default/services/kubernetes","uid":"1d
c6394b-b1d6-11e8-859a-
080027be08a0"},"spec":{"clusterIP":"10.96.0.1","ports":[{"name":"http
s","port":443,"protocol":"TCP","targetPort":8443}],"sessionAffinity":
"ClientIP","sessionAffinityConfig":{"clientIP":{"timeoutSeconds":1080
0}},"type":"ClusterIP"},"status":{"loadBalancer":{}}}
It will be very large in a log message:
Someone requires only “labels”:
{"labels":{"component":"apiserver","provider":"kubernetes"}
But another one requires “name” and “clusterIP”:
service: {"name":"kubernetes”,"clusterIP":"10.96.0.1"}
Necessary information depends on each context.
It is hard to define multiple loggers.
It is hard to set log-level for each logger on launching an app.
Replacement and Extraction [1/4]
app "my_app" {
logger {
replace_regex = [
{
from = "^service: (.*)$"
to = ”service ip: ${jqf('.spec.clusterIP', '1')}"
},
]
}
}
Extract “.spec.clusterIP” from the dict
works like jq command for JSON
Extract the IP
Replacement and Extraction [2/4]
app "my_app" {
logger {
replace_regex = [
{
from = "^service: (.*)$"
to = "ip: ${fg('blue')}${jqf('.spec.clusterIP', '1’)}${reset()}"
},
]
}
}
Colorize the string
Available Functions:
• jq_all(): Queries the dict and returns the list
• alias: jq()
• jq_first(): Queries the dict and return the first item
• alias: jqf()
• fg(): Sets the foreground color
• bg(): Sets the background color
• reset(): Reset the color
Replacement and Extraction [3/4]
A simple configuration for debugging
app "my_app" {
logger {
replace_regex = [
{
from = "^XXX (.*)$"
to = "${fg('red')}XXX 1${reset()}"
},
]
}
}
Displays log messages in red
which has the label “XXX”
Replacement and Extraction [4/4]
• Outputting large objects should be allowed in the debug log
• Use a tool to view the log with filters and replacements
• Filters can be configured in each context
• Jaffle supports merging multiple configurations
(described later)
Ideas to manage a large object in a message
Organizing Jaffle configurations
Setting Variables at runtime
• You can define variables in jaffle.hcl
• The variables can be set by environment
variables
variable "tornado_log_level" {
default = "debug"
}
variable "disable_frontend" {
default = false
}
kernel "py_kernel" {}
app "tornado_app" {
class = "jaffle.app.tornado.TornadoBridgeApp"
kernel = "py_kernel"
start = "tornado_app.start()"
logger {
level = "${var.tornado_log_level}"
}
options {
app_class = "tornado_spa_advanced.app.ExampleApp"
}
}
process "frontend" {
command = "yarn start"
tty = true
disabled = "${var.disable_frontend}"
}
Reference
Reference
Definitions
$ J_VAR_tornado_log_level=info 
J_VAR_disable_frontend=true 
jaffle start
Execution:
You don’t need to rewrite jaffle.hcl everytime
Merging Configurations
Example directory structure
project_repo/
├─ jaffle.hcl
├─ frontend.hcl
├─ backend.hcl
├─ my-jaffle.hcl
└─ src/
Base configuration (managed by git)
Config for frontend dev (managed by git)
Config for backend dev (managed by git)
Personal config (Ignored by .gitignore)
$ jaffle start jaffle.hcl backend.hcl my-jaffle.hcl
Run Jaffle for backend development:
Merges into on configuration
Especially useful to applying multiple filtering configurations
Architecture and
Implementation of Jaffle
Architecture [1/2]
JaffleSessionManager
JaffleKernelManager
JaffleKernelClient
JaffleStartCommand
App
Jupyter Kernel Session
ZeroMQ Socket for logging
Python Code/Response
via ZeroMQ
Log Message
Create Kernel
Session
Using Jupyter packages as a framework for Python
execution and communication between apps
Python Code
Architecture [2/2]
• Runs multiple Python apps in a Jupyter kernel session
• Using KernelManager, ContentsManager, SessionManager to
manage kernel sessions
• Using jupyter-client to communicate with kernels
• Uses ZeroMQ to collect log messages
• Includes the following “Apps”
• WatchdogApp: Executes code blocks and jobs on detecting
filesystem update
• PyTestRunnerApp: pytest runner
• TornadoBridgeApp: Starts/stops Tornado app
Inter-App Communication
• WatchdogApp and PyTestRunnerApp
are assigned to variables “watchdog”
and “pytest” respectively
• Apps can communicate with each other
via those variables
• Python code can be written in jaffle.hcl
(“code_blocks” in the left example)
kernel "py_kernel" {}
app "watchdog" {
class = "jaffle.app.watchdog.WatchdogApp"
kernel = "py_kernel"
options {
handlers = [{
# …
code_blocks = ["pytest.handle_watchdog_event({event})"]
}]
}
}
app "pytest" {
class = "jaffle.app.pytest.PyTestRunnerApp"
kernel = "py_kernel"
options {
# …
}
}
Refers the variable
watchdog is a variable
There is no special protocol between apps.
You only need to know the arguments
Write code
jaffle.hcl
Defining App
app "my_app" {
class = "my_module.MyApp"
kernel = "py_kernel"
options {
foo = 1
}
start = "my_app.bar()"
}
from jaffle.app.base import BaseJaffleApp, capture_method_output
from tornado import gen, ioloop
class MyApp(BaseJaffleApp):
def __init__(self, app_conf_data):
super().__init__(app_conf_data)
self.foo = self.options.get('foo')
self.log.info('foo: %d', self.foo)
@capture_method_output
def bar(self):
print('bar')
ioloop.IOLoop.current().add_callback(self.async_example)
@gen.coroutine
def async_example(self):
yield self.execute_code('{var} = 1 + 2', var='foo')
yield self.execute_command('echo hello')
yield self.execute_job('my_job')
Captures stdout/stderr
Getting an option
Call asynchrounously
my_app = my_module.MyApp(app_conf_data)
my_app.bar()
It will be executed as:
Usage (jaffle.hcl)
my_module.py
What’s Next
Extending Log Management
• Edit filtering rules interactively on the fly
• Preview the rules in real-time
• Saves the configurations created interactively
into a file
It is difficult to write regular expressions
Thank you!

More Related Content

What's hot

Making Structured Streaming Ready for Production
Making Structured Streaming Ready for ProductionMaking Structured Streaming Ready for Production
Making Structured Streaming Ready for ProductionDatabricks
 
Elk presentation 2#3
Elk presentation 2#3Elk presentation 2#3
Elk presentation 2#3uzzal basak
 
A Deep Dive into Structured Streaming in Apache Spark
A Deep Dive into Structured Streaming in Apache Spark A Deep Dive into Structured Streaming in Apache Spark
A Deep Dive into Structured Streaming in Apache Spark Anyscale
 
Data Summer Conf 2018, “Hands-on with Apache Spark for Beginners (ENG)” — Akm...
Data Summer Conf 2018, “Hands-on with Apache Spark for Beginners (ENG)” — Akm...Data Summer Conf 2018, “Hands-on with Apache Spark for Beginners (ENG)” — Akm...
Data Summer Conf 2018, “Hands-on with Apache Spark for Beginners (ENG)” — Akm...Provectus
 
Hadoop - Stock Analysis
Hadoop - Stock AnalysisHadoop - Stock Analysis
Hadoop - Stock AnalysisVaibhav Jain
 
InfluxDB IOx Tech Talks: Query Engine Design and the Rust-Based DataFusion in...
InfluxDB IOx Tech Talks: Query Engine Design and the Rust-Based DataFusion in...InfluxDB IOx Tech Talks: Query Engine Design and the Rust-Based DataFusion in...
InfluxDB IOx Tech Talks: Query Engine Design and the Rust-Based DataFusion in...InfluxData
 
Easy, scalable, fault tolerant stream processing with structured streaming - ...
Easy, scalable, fault tolerant stream processing with structured streaming - ...Easy, scalable, fault tolerant stream processing with structured streaming - ...
Easy, scalable, fault tolerant stream processing with structured streaming - ...Databricks
 
Apache Carbondata: An Indexed Columnar File Format for Interactive Query with...
Apache Carbondata: An Indexed Columnar File Format for Interactive Query with...Apache Carbondata: An Indexed Columnar File Format for Interactive Query with...
Apache Carbondata: An Indexed Columnar File Format for Interactive Query with...Spark Summit
 
Easy, scalable, fault tolerant stream processing with structured streaming - ...
Easy, scalable, fault tolerant stream processing with structured streaming - ...Easy, scalable, fault tolerant stream processing with structured streaming - ...
Easy, scalable, fault tolerant stream processing with structured streaming - ...Databricks
 
HadoopCon 2016 - 用 Jupyter Notebook Hold 住一個上線 Spark Machine Learning 專案實戰
HadoopCon 2016  - 用 Jupyter Notebook Hold 住一個上線 Spark  Machine Learning 專案實戰HadoopCon 2016  - 用 Jupyter Notebook Hold 住一個上線 Spark  Machine Learning 專案實戰
HadoopCon 2016 - 用 Jupyter Notebook Hold 住一個上線 Spark Machine Learning 專案實戰Wayne Chen
 
PSUG #52 Dataflow and simplified reactive programming with Akka-streams
PSUG #52 Dataflow and simplified reactive programming with Akka-streamsPSUG #52 Dataflow and simplified reactive programming with Akka-streams
PSUG #52 Dataflow and simplified reactive programming with Akka-streamsStephane Manciot
 
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...Databricks
 
AWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewAWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewDan Morrill
 
EuroPython 2015 - Big Data with Python and Hadoop
EuroPython 2015 - Big Data with Python and HadoopEuroPython 2015 - Big Data with Python and Hadoop
EuroPython 2015 - Big Data with Python and HadoopMax Tepkeev
 
Querying the Internet of Things: Streaming SQL on Kafka/Samza and Storm/Trident
Querying the Internet of Things: Streaming SQL on Kafka/Samza and Storm/TridentQuerying the Internet of Things: Streaming SQL on Kafka/Samza and Storm/Trident
Querying the Internet of Things: Streaming SQL on Kafka/Samza and Storm/TridentDataWorks Summit/Hadoop Summit
 
EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptx
EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptxEX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptx
EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptxvishal choudhary
 
Maximilian Michels – Google Cloud Dataflow on Top of Apache Flink
Maximilian Michels – Google Cloud Dataflow on Top of Apache FlinkMaximilian Michels – Google Cloud Dataflow on Top of Apache Flink
Maximilian Michels – Google Cloud Dataflow on Top of Apache FlinkFlink Forward
 

What's hot (20)

Making Structured Streaming Ready for Production
Making Structured Streaming Ready for ProductionMaking Structured Streaming Ready for Production
Making Structured Streaming Ready for Production
 
Elk presentation 2#3
Elk presentation 2#3Elk presentation 2#3
Elk presentation 2#3
 
A Deep Dive into Structured Streaming in Apache Spark
A Deep Dive into Structured Streaming in Apache Spark A Deep Dive into Structured Streaming in Apache Spark
A Deep Dive into Structured Streaming in Apache Spark
 
Apache PIG
Apache PIGApache PIG
Apache PIG
 
Data Summer Conf 2018, “Hands-on with Apache Spark for Beginners (ENG)” — Akm...
Data Summer Conf 2018, “Hands-on with Apache Spark for Beginners (ENG)” — Akm...Data Summer Conf 2018, “Hands-on with Apache Spark for Beginners (ENG)” — Akm...
Data Summer Conf 2018, “Hands-on with Apache Spark for Beginners (ENG)” — Akm...
 
Hadoop - Stock Analysis
Hadoop - Stock AnalysisHadoop - Stock Analysis
Hadoop - Stock Analysis
 
InfluxDB IOx Tech Talks: Query Engine Design and the Rust-Based DataFusion in...
InfluxDB IOx Tech Talks: Query Engine Design and the Rust-Based DataFusion in...InfluxDB IOx Tech Talks: Query Engine Design and the Rust-Based DataFusion in...
InfluxDB IOx Tech Talks: Query Engine Design and the Rust-Based DataFusion in...
 
Easy, scalable, fault tolerant stream processing with structured streaming - ...
Easy, scalable, fault tolerant stream processing with structured streaming - ...Easy, scalable, fault tolerant stream processing with structured streaming - ...
Easy, scalable, fault tolerant stream processing with structured streaming - ...
 
Apache Carbondata: An Indexed Columnar File Format for Interactive Query with...
Apache Carbondata: An Indexed Columnar File Format for Interactive Query with...Apache Carbondata: An Indexed Columnar File Format for Interactive Query with...
Apache Carbondata: An Indexed Columnar File Format for Interactive Query with...
 
Easy, scalable, fault tolerant stream processing with structured streaming - ...
Easy, scalable, fault tolerant stream processing with structured streaming - ...Easy, scalable, fault tolerant stream processing with structured streaming - ...
Easy, scalable, fault tolerant stream processing with structured streaming - ...
 
HadoopCon 2016 - 用 Jupyter Notebook Hold 住一個上線 Spark Machine Learning 專案實戰
HadoopCon 2016  - 用 Jupyter Notebook Hold 住一個上線 Spark  Machine Learning 專案實戰HadoopCon 2016  - 用 Jupyter Notebook Hold 住一個上線 Spark  Machine Learning 專案實戰
HadoopCon 2016 - 用 Jupyter Notebook Hold 住一個上線 Spark Machine Learning 專案實戰
 
PSUG #52 Dataflow and simplified reactive programming with Akka-streams
PSUG #52 Dataflow and simplified reactive programming with Akka-streamsPSUG #52 Dataflow and simplified reactive programming with Akka-streams
PSUG #52 Dataflow and simplified reactive programming with Akka-streams
 
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
From HelloWorld to Configurable and Reusable Apache Spark Applications in Sca...
 
Streaming SQL
Streaming SQLStreaming SQL
Streaming SQL
 
AWS Hadoop and PIG and overview
AWS Hadoop and PIG and overviewAWS Hadoop and PIG and overview
AWS Hadoop and PIG and overview
 
EuroPython 2015 - Big Data with Python and Hadoop
EuroPython 2015 - Big Data with Python and HadoopEuroPython 2015 - Big Data with Python and Hadoop
EuroPython 2015 - Big Data with Python and Hadoop
 
Querying the Internet of Things: Streaming SQL on Kafka/Samza and Storm/Trident
Querying the Internet of Things: Streaming SQL on Kafka/Samza and Storm/TridentQuerying the Internet of Things: Streaming SQL on Kafka/Samza and Storm/Trident
Querying the Internet of Things: Streaming SQL on Kafka/Samza and Storm/Trident
 
EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptx
EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptxEX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptx
EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptx
 
Maximilian Michels – Google Cloud Dataflow on Top of Apache Flink
Maximilian Michels – Google Cloud Dataflow on Top of Apache FlinkMaximilian Michels – Google Cloud Dataflow on Top of Apache Flink
Maximilian Michels – Google Cloud Dataflow on Top of Apache Flink
 
Hadoop training-in-hyderabad
Hadoop training-in-hyderabadHadoop training-in-hyderabad
Hadoop training-in-hyderabad
 

Similar to Jaffle: managing processes and log messages of multiple applications in development environment

Pemrograman Python untuk Pemula
Pemrograman Python untuk PemulaPemrograman Python untuk Pemula
Pemrograman Python untuk PemulaOon Arfiandwi
 
Doc manual 3.x
Doc manual 3.xDoc manual 3.x
Doc manual 3.xsetankecos
 
.NET @ apache.org
 .NET @ apache.org .NET @ apache.org
.NET @ apache.orgTed Husted
 
PyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsPyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsGraham Dumpleton
 
(2) c sharp introduction_basics_part_i
(2) c sharp introduction_basics_part_i(2) c sharp introduction_basics_part_i
(2) c sharp introduction_basics_part_iNico Ludwig
 
PyCon 2013 : Scripting to PyPi to GitHub and More
PyCon 2013 : Scripting to PyPi to GitHub and MorePyCon 2013 : Scripting to PyPi to GitHub and More
PyCon 2013 : Scripting to PyPi to GitHub and MoreMatt Harrison
 
Business logic with PostgreSQL and Python
Business logic with PostgreSQL and PythonBusiness logic with PostgreSQL and Python
Business logic with PostgreSQL and PythonHubert Piotrowski
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterHaehnchen
 
InfiniFlux collector
InfiniFlux collectorInfiniFlux collector
InfiniFlux collectorInfiniFlux
 
Hadoop cluster performance profiler
Hadoop cluster performance profilerHadoop cluster performance profiler
Hadoop cluster performance profilerIhor Bobak
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rulesSrijan Technologies
 
Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Robert Stern
 
Spotfire Integration & Dynamic Output creation
Spotfire Integration & Dynamic Output creationSpotfire Integration & Dynamic Output creation
Spotfire Integration & Dynamic Output creationAmbareesh Kulkarni
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 

Similar to Jaffle: managing processes and log messages of multiple applications in development environment (20)

Pemrograman Python untuk Pemula
Pemrograman Python untuk PemulaPemrograman Python untuk Pemula
Pemrograman Python untuk Pemula
 
11i Logs
11i Logs11i Logs
11i Logs
 
Doc manual 3.x
Doc manual 3.xDoc manual 3.x
Doc manual 3.x
 
.NET @ apache.org
 .NET @ apache.org .NET @ apache.org
.NET @ apache.org
 
PyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web ApplicationsPyCon AU 2012 - Debugging Live Python Web Applications
PyCon AU 2012 - Debugging Live Python Web Applications
 
(2) c sharp introduction_basics_part_i
(2) c sharp introduction_basics_part_i(2) c sharp introduction_basics_part_i
(2) c sharp introduction_basics_part_i
 
Gl qtp day 3 2
Gl qtp day 3   2Gl qtp day 3   2
Gl qtp day 3 2
 
PyCon 2013 : Scripting to PyPi to GitHub and More
PyCon 2013 : Scripting to PyPi to GitHub and MorePyCon 2013 : Scripting to PyPi to GitHub and More
PyCon 2013 : Scripting to PyPi to GitHub and More
 
Business logic with PostgreSQL and Python
Business logic with PostgreSQL and PythonBusiness logic with PostgreSQL and Python
Business logic with PostgreSQL and Python
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
 
InfiniFlux collector
InfiniFlux collectorInfiniFlux collector
InfiniFlux collector
 
Hadoop cluster performance profiler
Hadoop cluster performance profilerHadoop cluster performance profiler
Hadoop cluster performance profiler
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 
Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1Golang basics for Java developers - Part 1
Golang basics for Java developers - Part 1
 
Spotfire Integration & Dynamic Output creation
Spotfire Integration & Dynamic Output creationSpotfire Integration & Dynamic Output creation
Spotfire Integration & Dynamic Output creation
 
backend
backendbackend
backend
 
backend
backendbackend
backend
 
Log4j2
Log4j2Log4j2
Log4j2
 
Tibco business works
Tibco business worksTibco business works
Tibco business works
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 

Recently uploaded

Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 

Recently uploaded (20)

Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 

Jaffle: managing processes and log messages of multiple applications in development environment

  • 1. Jaffle: managing processes and log messages of multiple applications in development environment Masaki Yatsu PyCon JP Sep 18, 2018
  • 2. Agenda • Jaffle: Introducing new development tool • Motivation • Launching Python apps and external processes / Automatic job execution • Log management in the development environment • Managing Jaffle configurations • Architecture of Jaffle https://jaffle.readthedocs.io/ https://github.com/yatsu/jaffle Jaffle
  • 3. • Starts and stops multiple Python apps and external processes • Auto task execution on detecting filesystem update (e.g. auto-testing) • Integrated log output with filtering and replacing patterns • A framework to integrate Python apps in a Jupyter kernel session (described in the last section) What is Jaffle?
  • 4. Background • There are some tools and services to manage processes and logs in a production environment, but there is no easy solution for a development environment • Recent years… • Many applications and services must be integrated with each other • Each application and service outputs many and large data
  • 5. Launching Python apps and external processes / Automatic job execution
  • 6. Ex.1: Web dev with Tornado and React • Launches the backend Web API server • Launches two external processes • “yarn start” (Frontend dev server) • “jest” (JavaScript testing) • On detecting .py file update • Restart the Web API Server • Execute pytest • Displays integrated log messages https://jaffle.readthedocs.io/en/latest/cookbook/tornado_spa.html Backend development with Tornado (web framework) Frontend development with React
  • 7. Ex.2: Auto-pytest • Executes test_*.py when it is updated • Executes tests/foo/test_bar.py when the related implementation foo/bar.py is updated • Since pytest execution is always stand-by and reloads only Python modules under the current directory, it works fast • Cache-clear strategy is configurable https://jaffle.readthedocs.io/en/latest/cookbook/pytest.html
  • 8. Ex.2: Auto-pytest / Config file kernel "py_kernel" {} app "watchdog" { class = "jaffle.app.watchdog.WatchdogApp" kernel = "py_kernel" options { handlers = [{ watch_path = "pytest_example" patterns = ["*.py"] ignore_directories = true code_blocks = ["pytest.handle_watchdog_event({event})"] }] } } app "pytest" { class = "jaffle.app.pytest.PyTestRunnerApp" kernel = "py_kernel" options { args = ["-s", "-v", "—color=yes"] auto_test = ["pytest_example/tests/test_*.py"] auto_test_map { "pytest_example/**/*.py" = "pytest_example/tests/{}/test_{}.py" } } } App that watches filesystem update Executes the right-hand-side, when the left-hand-side is updated Executes the matched test file Defining Jupyter kernel (Python interpreter process) Refer the variable defined in the kernel Execute: $ jaffle start jaffle.hcl “jaffle.hcl” is optional: $ jaffle start Write jaffle.hcl as above:
  • 9. Ex.3: Sphinx auto-build / Config file kernel "py_kernel" { pass_env = ["PATH"] } app "watchdog" { class = "jaffle.app.watchdog.WatchdogApp" kernel = "py_kernel" options { handlers = [{ patterns = ["*/docs/*.*"] ignore_patterns = ["*/_build/*"] ignore_directories = true jobs = ["sphinx”, “refresh”] }] } } job "sphinx" { command = "sphinx-build -M html docs docs/_build" } job ”refresh" { command = ”osascript browser_refresh.scpt" } sphinx-build is executed automatically when .rst files under docs/ directory are updated Refers the job name Defines a job for command execution virtualenv requires this to pass environment variables to the kernel session tell application "Google Chrome" to tell the active tab of its first window reload end tell (for macOS)
  • 10. Ex.4: Jupyter Extension Development https://jaffle.readthedocs.io/en/latest/cookbook/jupyter_ext.html • Restarts Jupyter Notebook Server when .py file is updated • Executes “jupyter nbextension install” when .js files is updated kernel "py_kernel" { pass_env = ["PATH"] } app "watchdog" { class = "jaffle.app.watchdog.WatchdogApp" kernel = "py_kernel" options { handlers = [ { patterns = ["*.py"] ignore_directories = true clear_cache = ["jupyter_myext"] code_blocks = ["notebook.handle_watchdog_event({event})"] }, { patterns = ["*.js"] ignore_directories = true jobs = ["nbext_install"] }, ] } } app "notebook" { class = "jaffle.app.tornado.TornadoBridgeApp" kernel = "py_kernel" options { app_class = "notebook.notebookapp.NotebookApp" } start = "notebook.start()" } job "nbext_install" { command = "jupyter nbextension install jupyter_myext --user --overwrite" } Development of both backend (sever extension) and frontend (nbextension) Jupyter Notebook Server can run in the Tornado IOLoop which Jaffle initialized
  • 11. Log management in the development environment
  • 12. Problems of log management • Hard to understand the processing flow from multiple log files • Hard to find a message because there are so many log messages • Hard to get an information from a log message because some messages are large Log integration Filters out unnecessary log messages Extracts only the necessary information and emphasize them with colors
  • 13. Log Integration • All messages are displayed in a single flow • Each logger (app or process name) has its own unique color
  • 14. Log Filtering app "pytest" { class = "jaffle.app.pytest.PyTestRunnerApp" kernel = "py_kernel" logger { suppress_regex = [ "^platform ", "^cachedir:", "^rootdir:", "^plugins:", "collecting ...", "^collected ", ] } } Filters out unnecessary messages from pytest log
  • 15. Problem of large data included in a message $ kubectl get services kubernetes -o json { "apiVersion": "v1", "kind": "Service", "metadata": { "creationTimestamp": "2018-09-06T13:09:41Z", "labels": { "component": "apiserver", "provider": "kubernetes" }, "name": "kubernetes", "namespace": "default", "resourceVersion": "18", "selfLink": "/api/v1/namespaces/default/services/kubernetes", "uid": "1dc6394b-b1d6-11e8-859a-080027be08a0" }, "spec": { "clusterIP": "10.96.0.1", "ports": [ { "name": "https", "port": 443, "protocol": "TCP", "targetPort": 8443 } ], "sessionAffinity": "ClientIP", "sessionAffinityConfig": { "clientIP": { "timeoutSeconds": 10800 } }, "type": "ClusterIP" }, "status": { "loadBalancer": {} } } service: {"apiVersion":"v1","kind":"Service","metadata":{"creationTimestamp":" 2018-09- 06T13:09:41Z","labels":{"component":"apiserver","provider":"kubernete s"},"name":"kubernetes","namespace":"default","resourceVersion":"18", "selfLink":"/api/v1/namespaces/default/services/kubernetes","uid":"1d c6394b-b1d6-11e8-859a- 080027be08a0"},"spec":{"clusterIP":"10.96.0.1","ports":[{"name":"http s","port":443,"protocol":"TCP","targetPort":8443}],"sessionAffinity": "ClientIP","sessionAffinityConfig":{"clientIP":{"timeoutSeconds":1080 0}},"type":"ClusterIP"},"status":{"loadBalancer":{}}} It will be very large in a log message: Someone requires only “labels”: {"labels":{"component":"apiserver","provider":"kubernetes"} But another one requires “name” and “clusterIP”: service: {"name":"kubernetes”,"clusterIP":"10.96.0.1"} Necessary information depends on each context. It is hard to define multiple loggers. It is hard to set log-level for each logger on launching an app.
  • 16. Replacement and Extraction [1/4] app "my_app" { logger { replace_regex = [ { from = "^service: (.*)$" to = ”service ip: ${jqf('.spec.clusterIP', '1')}" }, ] } } Extract “.spec.clusterIP” from the dict works like jq command for JSON Extract the IP
  • 17. Replacement and Extraction [2/4] app "my_app" { logger { replace_regex = [ { from = "^service: (.*)$" to = "ip: ${fg('blue')}${jqf('.spec.clusterIP', '1’)}${reset()}" }, ] } } Colorize the string Available Functions: • jq_all(): Queries the dict and returns the list • alias: jq() • jq_first(): Queries the dict and return the first item • alias: jqf() • fg(): Sets the foreground color • bg(): Sets the background color • reset(): Reset the color
  • 18. Replacement and Extraction [3/4] A simple configuration for debugging app "my_app" { logger { replace_regex = [ { from = "^XXX (.*)$" to = "${fg('red')}XXX 1${reset()}" }, ] } } Displays log messages in red which has the label “XXX”
  • 19. Replacement and Extraction [4/4] • Outputting large objects should be allowed in the debug log • Use a tool to view the log with filters and replacements • Filters can be configured in each context • Jaffle supports merging multiple configurations (described later) Ideas to manage a large object in a message
  • 21. Setting Variables at runtime • You can define variables in jaffle.hcl • The variables can be set by environment variables variable "tornado_log_level" { default = "debug" } variable "disable_frontend" { default = false } kernel "py_kernel" {} app "tornado_app" { class = "jaffle.app.tornado.TornadoBridgeApp" kernel = "py_kernel" start = "tornado_app.start()" logger { level = "${var.tornado_log_level}" } options { app_class = "tornado_spa_advanced.app.ExampleApp" } } process "frontend" { command = "yarn start" tty = true disabled = "${var.disable_frontend}" } Reference Reference Definitions $ J_VAR_tornado_log_level=info J_VAR_disable_frontend=true jaffle start Execution: You don’t need to rewrite jaffle.hcl everytime
  • 22. Merging Configurations Example directory structure project_repo/ ├─ jaffle.hcl ├─ frontend.hcl ├─ backend.hcl ├─ my-jaffle.hcl └─ src/ Base configuration (managed by git) Config for frontend dev (managed by git) Config for backend dev (managed by git) Personal config (Ignored by .gitignore) $ jaffle start jaffle.hcl backend.hcl my-jaffle.hcl Run Jaffle for backend development: Merges into on configuration Especially useful to applying multiple filtering configurations
  • 24. Architecture [1/2] JaffleSessionManager JaffleKernelManager JaffleKernelClient JaffleStartCommand App Jupyter Kernel Session ZeroMQ Socket for logging Python Code/Response via ZeroMQ Log Message Create Kernel Session Using Jupyter packages as a framework for Python execution and communication between apps Python Code
  • 25. Architecture [2/2] • Runs multiple Python apps in a Jupyter kernel session • Using KernelManager, ContentsManager, SessionManager to manage kernel sessions • Using jupyter-client to communicate with kernels • Uses ZeroMQ to collect log messages • Includes the following “Apps” • WatchdogApp: Executes code blocks and jobs on detecting filesystem update • PyTestRunnerApp: pytest runner • TornadoBridgeApp: Starts/stops Tornado app
  • 26. Inter-App Communication • WatchdogApp and PyTestRunnerApp are assigned to variables “watchdog” and “pytest” respectively • Apps can communicate with each other via those variables • Python code can be written in jaffle.hcl (“code_blocks” in the left example) kernel "py_kernel" {} app "watchdog" { class = "jaffle.app.watchdog.WatchdogApp" kernel = "py_kernel" options { handlers = [{ # … code_blocks = ["pytest.handle_watchdog_event({event})"] }] } } app "pytest" { class = "jaffle.app.pytest.PyTestRunnerApp" kernel = "py_kernel" options { # … } } Refers the variable watchdog is a variable There is no special protocol between apps. You only need to know the arguments Write code jaffle.hcl
  • 27. Defining App app "my_app" { class = "my_module.MyApp" kernel = "py_kernel" options { foo = 1 } start = "my_app.bar()" } from jaffle.app.base import BaseJaffleApp, capture_method_output from tornado import gen, ioloop class MyApp(BaseJaffleApp): def __init__(self, app_conf_data): super().__init__(app_conf_data) self.foo = self.options.get('foo') self.log.info('foo: %d', self.foo) @capture_method_output def bar(self): print('bar') ioloop.IOLoop.current().add_callback(self.async_example) @gen.coroutine def async_example(self): yield self.execute_code('{var} = 1 + 2', var='foo') yield self.execute_command('echo hello') yield self.execute_job('my_job') Captures stdout/stderr Getting an option Call asynchrounously my_app = my_module.MyApp(app_conf_data) my_app.bar() It will be executed as: Usage (jaffle.hcl) my_module.py
  • 29. Extending Log Management • Edit filtering rules interactively on the fly • Preview the rules in real-time • Saves the configurations created interactively into a file It is difficult to write regular expressions