<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Fruch's Blog</title>
 <link href="http://fruch.github.io/atom.xml" rel="self"/>
 <link href="http://fruch.github.io"/>
 <updated>2020-12-31T20:28:54+00:00</updated>
 <id>http://fruch.github.io</id>
 <author>
   <name>Israel Fruchter</name>
   <email>israel.fruchter@gmail.com</email>
 </author>

 
 <entry>
   <title>Taking Github Actions for a walk in the park</title>
   <link href="http://fruch.github.io/2020/12/29/github-actions"/>
   <updated>2020-12-29T00:00:00+00:00</updated>
   <id>http://fruch.github.io/2020/12/29/github-actions</id>
   <content type="html">
&lt;h1 id=&quot;taking-github-actions-for-a-walk-in-the-park&quot;&gt;Taking Github Actions for a walk in the park&lt;/h1&gt;

&lt;h2 id=&quot;travis-started-to-scare-me-a-bit&quot;&gt;Travis started to scare me a bit&lt;/h2&gt;

&lt;p&gt;People were talking about github actions for a while now, lot of hype around it.
I myself was quite happy with the things I’ve managed to get done with &lt;a href=&quot;https://travis-ci.org/&quot;&gt;Travis&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But then came in this announcement from travis: &lt;a href=&quot;https://blog.travis-ci.com/2020-11-02-travis-ci-new-billing&quot;&gt;“The new pricing model for travis-ci.com”&lt;/a&gt;.
I was reading via lot of the backlash in tweeter about it, and after carefully reading the announcement itself, I was starting to think that the work I did for &lt;a href=&quot;https://github.com/scylladb/python-driver&quot;&gt;scylla-driver&lt;/a&gt; was counting on &lt;a href=&quot;https://travis-ci.org/&quot;&gt;Travis&lt;/a&gt; too much.&lt;/p&gt;

&lt;p&gt;Recently I’ve start seeing long queues for job triggers in travis, and I was starting to have second thoughts about picking travis. (not so long ago, less than a year ago)&lt;/p&gt;

&lt;h2 id=&quot;the-sweet-setup-i-had-in-travis&quot;&gt;The sweet setup I had in Travis&lt;/h2&gt;

&lt;p&gt;As a recap for &lt;a href=&quot;https://github.com/scylladb/python-driver&quot;&gt;scylla-driver&lt;/a&gt;, since it’s a c based package, heavily using &lt;a href=&quot;https://cython.org/&quot;&gt;cython&lt;/a&gt;.
We are building python wheels for windows, mac, linux, ranging from python2.7 to python3.9, and pypy. (also using the &lt;a href=&quot;https://travis-ci.org/&quot;&gt;Travis&lt;/a&gt; experimental aarch64 and ppc64le support)&lt;/p&gt;

&lt;p&gt;For building the wheels we are using &lt;a href=&quot;https://github.com/joerick/cibuildwheel&quot;&gt;cibuildwheel&lt;/a&gt;, which is a nifty tool that magically keep all know how, on how building wheels correctly on multiple platforms.
In linux, it’s using the official docker images provided by the [Python Packaging Authority
] for manylinux2014.
And on windows and mac equivalents with the correct set to needed tool to get you wheel happily containing all the need dynamic libraries it depended on&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/joerick/cibuildwheel&quot;&gt;cibuildwheel&lt;/a&gt; also comes with readily available examples for all the major CI system out there&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://travis-ci.org/github/scylladb/python-driver/builds/709882917&quot;&gt;&lt;img src=&quot;http://fruch.github.io/assets/img/python-driver-release.png&quot; width=&quot;100%&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/joerick/cibuildwheel&quot;&gt;cibuildwheel&lt;/a&gt; is also helping you in running unittest ontop of each built wheel (since in my case the setup is a bit complex, getting it installed and compile across the board was hard, we we’re skipping some unittest on some platforms)&lt;/p&gt;

&lt;p&gt;Travis was also running our integration test suite, and running it on our PRs, and automatically uploading all the wheels and source distribution to Pypi.&lt;/p&gt;

&lt;p&gt;I was working on this setup for long week, with a tight deadline for it to be ready for &lt;a href=&quot;https://ep2020.europython.eu/&quot;&gt;europython2020&lt;/a&gt;, thanks to &lt;a href=&quot;https://twitter.com/ultrabug&quot;&gt;@ultrabug&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;github-actions&quot;&gt;Github actions&lt;/h2&gt;

&lt;p&gt;For a while I was a bit unsure if it would be a match to what I had in travis. But one day our own Jenkins server was down for maintenance, and a big portion of my day was clear case of that.&lt;/p&gt;

&lt;p&gt;I’ve started with copy-pasting &lt;a href=&quot;https://github.com/joerick/cibuildwheel&quot;&gt;cibuildwheel&lt;/a&gt; github actions &lt;a href=&quot;https://cibuildwheel.readthedocs.io/en/stable/setup/#github-actions&quot;&gt;example&lt;/a&gt;, and worked my way from there.&lt;/p&gt;

&lt;p&gt;When I’ve started adding all the different unittest and platforms, I was struggling a bit with how the matrix is working, and how conditional steps works.&lt;/p&gt;

&lt;p&gt;It ended up something like this, almost identical to what I had in travis:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Build and upload to PyPi&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pull_request&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;s&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;build_wheels&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Build wheels $ ($)&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;contains(github.event.pull_request.labels.*.name, 'test-build') || github.event_name == 'push' &amp;amp;&amp;amp; endsWith(github.event.ref, 'scylla')&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;strategy&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;fail-fast&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;matrix&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ubuntu-18.04&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;x86_64&lt;/span&gt;

          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ubuntu-18.04&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;i686&lt;/span&gt;

          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ubuntu-18.04&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;PyPy&lt;/span&gt;

          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;windows-latest&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;win32&lt;/span&gt;

          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;windows-latest&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;win64&lt;/span&gt;

          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;windows-latest&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;PyPy&lt;/span&gt;

          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;macos-latest&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;all&lt;/span&gt;

          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;macos-latest&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;PyPy&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We had a nice twist that we didn’t have before, but now we can control from github PR which part of my pipeline would run using label, since github actions is so tightly integrated you can lookup almost anything related to the PR.&lt;/p&gt;

&lt;h2 id=&quot;github-actions---ui&quot;&gt;Github Actions - UI&lt;/h2&gt;

&lt;p&gt;This is how the final thing looks like:
&lt;a href=&quot;https://github.com/scylladb/python-driver/actions/runs/446668339&quot;&gt;&lt;img src=&quot;http://fruch.github.io/assets/img/github_actions.png&quot; width=&quot;100%&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;logging is a bit weird to watch while it’s running, but after the fact the log are very tidy to look at&lt;/p&gt;

&lt;h2 id=&quot;late-surprise---cross-compile-using-qemu&quot;&gt;Late surprise - cross compile using qemu&lt;/h2&gt;

&lt;p&gt;With almost perfect timing I’ve run into this
https://github.com/joerick/cibuildwheel/pull/482
by &lt;a href=&quot;https://github.com/asfaltboy&quot;&gt;Pavel Savchenko&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was trying all kind of things to get aarch64 support, but this PR figure it out quite nicely, with one magic step:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Set up QEMU&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;qemu&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;docker/setup-qemu-action@v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;platforms&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For reference the full &lt;a href=&quot;https://github.com/scylladb/python-driver/actions/runs/446668338/workflow&quot;&gt;workflow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can have docker using qemu to run docker instances based on different cpu architecture, it’s horribly slow but it’s working.&lt;/p&gt;

&lt;p&gt;And nice side effect I’ve learned how to run it locally, so I can debug those things. Something I haven’t figured when running with Travis, apparently travis was using the same trick on their experimental support for those architectures.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;Github actions works out of the box, with almost zero fraction, almost anything I could think about I’ve found a readily available step I can pickup, very impressing.&lt;/p&gt;

&lt;p&gt;One thing I haven’t yet tried out, is using self hosted runner, hopefully I won’t need it.
Cause who want to babysit anther server on his own, or worse, a bunch of them.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>How much fun was EuroPython 2020</title>
   <link href="http://fruch.github.io/2020/07/29/europython-2020"/>
   <updated>2020-07-29T00:00:00+00:00</updated>
   <id>http://fruch.github.io/2020/07/29/europython-2020</id>
   <content type="html">
&lt;h1 id=&quot;how-much-fun-was-europython-2020&quot;&gt;How much fun was EuroPython 2020&lt;/h1&gt;

&lt;h2 id=&quot;pyconil-got-canceled&quot;&gt;&lt;a href=&quot;https://pycon.org.il/2020/&quot;&gt;#pyconil&lt;/a&gt; got canceled&lt;/h2&gt;

&lt;p&gt;This year I’ve finally got enough courage and will, and I had 2 submissions for &lt;a href=&quot;https://pycon.org.il/2020/&quot;&gt;#pyconil&lt;/a&gt;.
COVID-19 had other plans, and &lt;a href=&quot;https://pycon.org.il/2020/&quot;&gt;#pyconil&lt;/a&gt; was canceled&lt;/p&gt;

&lt;p&gt;I’ve told &lt;a href=&quot;https://twitter.com/ultrabug&quot;&gt;@ultrabug&lt;/a&gt; about this (Numberly CTO, Alexys Jacob), after a few weeks he surprised me with telling me he’s gonna present &lt;a href=&quot;(https://github.com/scylladb/python-driver)&quot;&gt;scylla-driver&lt;/a&gt; in europython2020, the shard-aware driver we were working on in the last 6 months.&lt;/p&gt;

&lt;p&gt;At the time it wasn’t yet ready nor publish.
(Also found out that Numberly were sponsoring europython for years now)
Took me a few seconds to figure that he just set me deadline without my consent…&lt;/p&gt;

&lt;p&gt;Fast-forwarding a bit, and &lt;a href=&quot;(https://github.com/scylladb/python-driver)&quot;&gt;scylla-driver&lt;/a&gt; initial release came out: 
https://pypi.org/project/scylla-driver/3.21.0/&lt;/p&gt;

&lt;p&gt;And my tickets for europython2020 were booked…&lt;/p&gt;

&lt;h2 id=&quot;discord-is-fun&quot;&gt;Discord is fun&lt;/h2&gt;

&lt;p&gt;Few days before the date, I’ve got an email with instruction to connect to the discord of europython2020, since it’s my first COVID-19 online conference, I’ve registered and login straight away.&lt;/p&gt;

&lt;p&gt;It was really nice to be start to start talking with people and meet them a few days before&lt;/p&gt;

&lt;p&gt;Each track got its own chat room, backed with zoom webinar and online youtube stream
each talk got its own chat room, so people can promote their and answer question before and after the talks.
Sponsors had rooms too, and all the sprints had rooms (we’ll get to that later on)&lt;/p&gt;

&lt;p&gt;Talk about timing, day before europython2020, this press release came out
https://www.scylladb.com/press-release/discord-chooses-scylla-core-storage-layer/&lt;/p&gt;

&lt;h2 id=&quot;talks--day-1&quot;&gt;Talks — Day 1&lt;/h2&gt;

&lt;p&gt;The opening keynote was cancelled cause of technical difficulties, that lost touch with whom was supposed to talk. (it rescheduled to next day)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://github.com/eliasmistler&quot;&gt;Elias Mistler&lt;/a&gt; was talking about &lt;a href=&quot;https://ep2020.europython.eu/talks/83SnxW9-how-to-write-multi-paradigm-code/&quot;&gt;“How to write multi-paradigm code”&lt;/a&gt; show casing and coding live a sudoku solver, with functional and object originated approaches, and how to mix them both.
The code is available as &lt;a href=&quot;https://github.com/eliasmistler/europython2020-multi-paradigm-sudoku&quot;&gt;notebook&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/in/boyan-miletic/&quot;&gt;Bojan Miletic&lt;/a&gt; was talking about &lt;a href=&quot;https://ep2020.europython.eu/talks/5e5RyUN-django-testing-on-steroird-pytest-hypothesis/&quot;&gt;“Django Testing on Steroid: pytest + Hypothesis”&lt;/a&gt; — shows the basic usage of hypothesis, I’m hear about hypothesis all over the place, maybe it will bring me one step close to use is in one of my projects&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://twitter.com/MartinChristen&quot;&gt;Martin Christen&lt;/a&gt; gave a very cool demo of &lt;a href=&quot;https://ep2020.europython.eu/talks/3TkNjfe-pyrt-computer-graphics-in-jupyter-notebooks-for-fun-and-teaching/&quot;&gt;“pyRT - Computer Graphics in Jupyter Notebooks for Fun and Teaching”&lt;/a&gt; - I love Jupyter notebook visual trick, and I love 3d. So this one I enjoyed a lot, Martin was quite a performer and funny. I strongly recommend trying out the &lt;a href=&quot;https://github.com/martinchristen/EuroPython2020&quot;&gt;demo&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://twitter.com/gjbernat&quot;&gt;Bernat Gabor&lt;/a&gt; gave an excellent talk
&lt;a href=&quot;https://ep2020.europython.eu/talks/D2SG8Vb-lessons-from-the-trenches-rewriting-and-re-releasing-virtualenv/&quot;&gt;“Lessons from the Trenches: rewriting and re-releasing virtualenv”&lt;/a&gt;
about a big refactoring virtualenv had, packaging is a subject close to my heart. This is an excellent lesson on how to approach major refactor and a reminder that it would always take more time than you’ll estimate it.
I must say that this change, from a POV of a heavy user of virtualenv, wasn’t even noticed.
When he was demoing a few things I’ve realized that I’ve seen it in logs, but didn’t know the big story happing behind the scenes.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In the next one, &lt;a href=&quot;https://twitter.com/pdgjones&quot;&gt;Philip Jones&lt;/a&gt; was building a ASGI server from scratch, show the details of the ASGI protocol — &lt;a href=&quot;https://ep2020.europython.eu/talks/4g2en8S-an-asgi-server-from-scratch/&quot;&gt;“An ASGI Server from scratch”&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://ep2020.europython.eu/talks/a-deep-dive-and-comparison-of-python-drivers-for-cassandra-and-scylla/&quot;&gt;“A deep dive and comparison of Python drivers for Cassandra and Scylla”&lt;/a&gt; — &lt;a href=&quot;https://twitter.com/ultrabug&quot;&gt;Alexys&lt;/a&gt; great slides (which I had a peek at few days before)with lot of emojis, going down to the details of how cassandra/scylla hash ring works, and how scylla shard share nothing architecture is use by the &lt;a href=&quot;(https://github.com/scylladb/python-driver)&quot;&gt;scylla-driver&lt;/a&gt; fork we work on for the last few months.
And he finished with data from Numberly production before/after moving to shard aware client, 2x-2.5x speed up in response time
I was live tweeting the whole thing into our company slack…&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ep2020.europython.eu/talks/5PDef3W-elegant-exception-handling/&quot;&gt;“Elegant Exception Handling”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ep2020.europython.eu/talks/CeKGczx-best-practices-for-production-ready-docker-packaging/&quot;&gt;“Best practices for production-ready Docker packaging”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ep2020.europython.eu/talks/4yCL9yy-pluggable-architecture/&quot;&gt;“Pluggable Architecture”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ep2020.europython.eu/talks/6Le7GKY-writing-zenlike-python/&quot;&gt;“Writing Zenlike Python”&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;social--the-missing-e-in-my-whisky&quot;&gt;Social — the missing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt; in my whisky&lt;/h2&gt;

&lt;p&gt;During the whole day I was playing cat and mouse with people, trying to bring them into the open track, to have a face to face meeting,
only later after all the sessions end, some people came in, most of them were the part of the organizing team. Every one where show their beer or whisky that they were drinking. &lt;a href=&quot;https://github.com/kgaughan&quot;&gt;Keith Gaughan&lt;/a&gt; was laughing at the ice in my whisky, and also thought me a real whisky is spelled with whiskey with an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;e&lt;/code&gt; in it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/malemburg&quot;&gt;Marc-Andre Lemburg&lt;/a&gt; was talking about the challenges they have as organizers, one thing led to anther, and I ask how can I help. He said they need a hand with handling the tweeter account, and that he’ll hook me tomorrow with whom handle it.&lt;/p&gt;

&lt;p&gt;After a few more rounds of whisky, I call it a day.&lt;/p&gt;

&lt;h2 id=&quot;talks--day-2&quot;&gt;Talks — Day 2&lt;/h2&gt;

&lt;p&gt;TODO:&lt;/p&gt;

&lt;h2 id=&quot;sprints&quot;&gt;Sprints&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;packaging -&lt;/li&gt;
  &lt;li&gt;hypothesis -&lt;/li&gt;
  &lt;li&gt;terminusdb-client -&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>My DevopsDaysTLV Summary</title>
   <link href="http://fruch.github.io/2019/12/22/devopsdaytlv-summary"/>
   <updated>2019-12-22T00:00:00+00:00</updated>
   <id>http://fruch.github.io/2019/12/22/devopsdaytlv-summary</id>
   <content type="html">
&lt;h1 id=&quot;my-devopsdaystlv-summary&quot;&gt;My DevopsDaysTLV Summary&lt;/h1&gt;

&lt;h2 id=&quot;late-birds&quot;&gt;Late birds&lt;/h2&gt;

&lt;p&gt;Sunday night my boss asks me if I want to come to &lt;a href=&quot;https://devopsdays.org/events/2019-tel-aviv/welcome/&quot;&gt;#DevopsDaysTLV&lt;/a&gt;,
reading the program, seems like intersting talks, but no ticket left for the first day.
Once we got the tickets, I know what’s Early Bird tickets, now I’ve found out there’s Late Birds tickets.&lt;/p&gt;

&lt;h2 id=&quot;rockstar-saves-the-day&quot;&gt;Rockstar saves the day&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/giltayar&quot;&gt;Gil Tayar&lt;/a&gt; wrote on tweeter that he’s gonna fill in for someone who could make it, since she cought the flu.
I was publicly devestanded that it’s gonna be on the first day, and I won’t get to meet Gil face to face.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My DM flahses&lt;/strong&gt; Gil supprises me with giving me his +1 ticket, I title him as a rock-star, not even gussing what to come.&lt;/p&gt;

&lt;h2 id=&quot;day-one&quot;&gt;Day One&lt;/h2&gt;

&lt;p&gt;Gil picks up my tag, while I get lost a bit in the convention center. Following other lost nerds, got me walking in circles around the whole place.&lt;/p&gt;

&lt;p&gt;Didn’t know too many people, Devops isn’t excatly my field (and beyond pycon.il I don’t attend too many confrences).
I was supprised to see Anna from ElasticSearch too, didn’t know she’ll be there. I was really existed to meet her face to face, and not only via zoom chat.&lt;/p&gt;

&lt;p&gt;Picking some stickers and swag, and then keynote started.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://twitter.com/nicolefv&quot;&gt;Dr. Nicole Forsfren&lt;/a&gt; was talking about the &lt;a href=&quot;https://cloud.google.com/devops/&quot;&gt;2019 State of DevOps Report&lt;/a&gt;, it’s was nice to see that she has numbers to proof Devops is working very good for some companies, and the trend of compenies excecuting faster is growing.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Then I’ve heard &lt;a href=&quot;https://twitter.com/omerlh&quot;&gt;Omer Lev Hevroni&lt;/a&gt;, tells his tale, on how they had a leakge of cerdentionals, and the joureny and tools they used to reduce the chances it would happen again. (One more tweeter figure, that become a bit more real for me, that day)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;And then Gil talk about #egoprogramofobia, really proving he’s a rockstar, making the crowd sing along with him while he trys to drive fear of own code out of people.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Coming up next, I’ve heard &lt;a href=&quot;https://twitter.com/ShlomiNoach&quot;&gt;Shlomi Noach&lt;/a&gt;, from github. Explianing the CAP Theorem and extending it a bit to try to give it some more reasnable close to real-life interpertention (maybe now I’ll rememeber all what each letter stands for).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Food break&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Regev Golan was talking on what you need to consider while depolying an app that uses GPUs, best practicates and thing to consider while deploying.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://twitter.com/erikzaadi&quot;&gt;Erik Zaadi&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://twitter.com/korndaniel1&quot;&gt;Dainel Korn&lt;/a&gt;, made a great talk about the lesson we should learn from Rick &amp;amp; Morty, it was really funny. Erik dressed a pickle, was a sight not easily forgotten.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then I had to split, to take my someone of kindergarden…&lt;/p&gt;

&lt;h2 id=&quot;day-two&quot;&gt;Day Two&lt;/h2&gt;

&lt;p&gt;While I’m waltzing in that morning, I’ve met Maish in his new role in the AWS booth, he was talking with Florian. Isreali of me I’ve started talking hebrew and cut thier converstaion in the middle. Took me a few moments to figure it out and appologise. Few words with Florian, and I’ve decided I defentliy goona enter his talk.&lt;/p&gt;

&lt;p&gt;My late bird boss joined in, coming a bit injerd.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Brian Murphy from GeekSeat was giving the keynote, expliaing his approch to taking decietion about new tech, and how RFC process is importent to every team.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://twitter.com/xahteiwi&quot;&gt;Florian Haas&lt;/a&gt; — Communication for distributed teams talk was spot one. He was talking about the missuse of diffrent communication medium while my boss show me life examples on his phone for everything Florian is talking about.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://twitter.com/xeraa&quot;&gt;Philip Krenn&lt;/a&gt; from elastic, packed the room, and I was standing hearing more the logistics of handling a small flood in the side of the room. I guess he’s talk was intersting enough for everyone to squize in.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://twitter.com/annapavt&quot;&gt;Anna Bankirer&lt;/a&gt; was talking about object oriented desgin. It was nice but I would have jumped stright into examples, and minize the talk intro about OOD/OOP, yeah I know the theam was “back to fundmentals”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://twitter.com/elazarl&quot;&gt;Elazar Leibovich&lt;/a&gt; — talked about docker networking, and how to share a port from a running docker instance without a restart, how exactly docker networking is working is always a puzzle to people, me included. Just a week ago I’ve myself in need of a white board to explien to someone how docker instances can communicate internall, and why a host port isn’t needed for that.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/in/rbotzer/&quot;&gt;Ronen Botzer&lt;/a&gt; from Aerospike, was getting pissed at compenies that doing a grabge benchmarks. At least he was mentioning us (&lt;a href=&quot;https://www.scylladb.com/&quot;&gt;scylladb&lt;/a&gt;), and he told me at the first day he’s gonna talk about it&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://twitter.com/flyingbarron&quot;&gt;Robert Barron&lt;/a&gt; was closing the session with a great talk about the Appllo Missions to the Moon, while demostanting that almost the pinciples we know in devops were used in those missions, Kohelet was right while saying &lt;em&gt;“nothing new under the sun”&lt;/em&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beers and Sufganiut for finising up.&lt;/p&gt;

&lt;p&gt;I enjoyed it very much…&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Introducing pytest-elk-reporter</title>
   <link href="http://fruch.github.io/2019/06/24/pytest-elk-reporter"/>
   <updated>2019-06-24T00:00:00+00:00</updated>
   <id>http://fruch.github.io/2019/06/24/pytest-elk-reporter</id>
   <content type="html">
&lt;h1 id=&quot;pytest-elk-reporter&quot;&gt;pytest-elk-reporter&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;tl;td&lt;/strong&gt;: https://github.com/fruch/pytest-elk-reporter&lt;/p&gt;

&lt;h2 id=&quot;history&quot;&gt;History&lt;/h2&gt;
&lt;p&gt;Few years back I’ve wrote a post about how I’ve connected python based test to ELK setup - &lt;a href=&quot;http://fruch.github.io/blog/2014/10/30/ELK-is-fun&quot;&gt;“ELK is fun”&lt;/a&gt;, it was using an xunit xml, parsing it and sending it via Logstash.&lt;/p&gt;

&lt;p&gt;Over time I’ve learn a lot about ElasticSearch and it’s friend Kibana, using them as a tool to handle logs. and also as a backend for a search component on my previous job.&lt;/p&gt;

&lt;p&gt;So now I know logstash isn’t needed for reporting test result, posting straight into elasticsearch is easier and gives you better control, ES is doing anything “automagiclly” anyhow nowadays.&lt;/p&gt;

&lt;h2 id=&quot;what-can-it-do-&quot;&gt;What can it do ?&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;collect&lt;/strong&gt; as much information as you can about one test results and running environment and send it to elasticsearch.
    &lt;ul&gt;
      &lt;li&gt;data like git commit/sha from current directory&lt;/li&gt;
      &lt;li&gt;jenkins environment variables, like job id and username triggered the job.&lt;/li&gt;
      &lt;li&gt;cool tracebacks which pytest excels at.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;extend&lt;/strong&gt; - let user configure (like target address and credentials) it from code, and add data of their own to each session or test.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;tricks-ive-picked-on-the-way&quot;&gt;Tricks I’ve picked on the way&lt;/h2&gt;

&lt;p&gt;Every time I start a new package, I learn a few new things, here’s a few I’m happy about this time:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Created the package with &lt;a href=&quot;https://github.com/pytest-dev/cookiecutter-pytest-plugin&quot;&gt;cookiecutter-pytest-plugin&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;I’m using &lt;a href=&quot;https://pre-commit.com&quot;&gt;pre-commit&lt;/a&gt;&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;a href=&quot;https://github.com/python/black&quot;&gt;black&lt;/a&gt; - instead of the old friend &lt;a href=&quot;https://github.com/hhatto/autopep8&quot;&gt;autopep8&lt;/a&gt;.&lt;/p&gt;
      &lt;/li&gt;
      &lt;li&gt;
        &lt;p&gt;&lt;a href=&quot;https://www.pylint.org/&quot;&gt;pylint&lt;/a&gt; in both python27 and python36 to keep the code clean of silly mistakes.&lt;/p&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://travis-ci.org/fruch/pytest-elk-reporter&quot;&gt;Travis&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;build and test with Tox on all possible python versions.&lt;/p&gt;

    &lt;p&gt;also uploading wheels to pypi based on tags.&lt;/p&gt;

    &lt;p&gt;thanks to &lt;a href=&quot;https://github.com/pypa/setuptools_scm&quot;&gt;setuptools_scm&lt;/a&gt; version no need to edit files for setting version number.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://ci.appveyor.com/project/fruch/pytest-elk-reporter&quot;&gt;Appveyor&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;I also cover windows own little issue (non found so far).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://codecov.io/gh/fruch/pytest-elk-reporter/commits&quot;&gt;Codecov&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;really like that it can collect from multiple run, for example both linux and windows tests run, which helps to show the total coverage.&lt;/p&gt;

    &lt;p&gt;got me to 93% line coverage (and going down as I add more code).&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;the-bad-stuff---aka-things-i-need-to-improve&quot;&gt;The bad stuff - a.k.a things I need to improve&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Documentation&lt;/strong&gt; - I’ve mostly wrote test, zero docs.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Name&lt;/strong&gt; - it’s a bit boring, and might conflict with other plugins.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Kibana Dashboards examples&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;I should really include some sample kibana dashboard to show the strength of it, it’s own test data is a bit boring.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;auto generating and upload of docs&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;I’ve tried using Travis Deploy to github Pages, didn’t exactly nailed, or got it working as I expect, maybe I should try &lt;a href=&quot;https://readthedocs.org/&quot;&gt;readthedocs&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;pytest-xdist&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;I still need to test it with xdist, it’s going to make thing a more tricker, as usual.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-you-should-next&quot;&gt;What you should next&lt;/h2&gt;

&lt;p&gt;Go grab &lt;a href=&quot;https://github.com/fruch/pytest-elk-reporter&quot;&gt;it&lt;/a&gt;, git it a star, fork it.&lt;/p&gt;

&lt;p&gt;I’m waiting for your PRs, and your stories on how it’s help you tame a whole bunch of tests.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;    &lt;span class=&quot;c&quot;&gt;# forgot to show how to install :\&lt;/span&gt;
    pip &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;pytest-elk-reporter&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</content>
 </entry>
 
 <entry>
   <title>Microsoft - amazing stuff, WSL, VSCode</title>
   <link href="http://fruch.github.io/2017/12/07/microsoft-wsl-vscode"/>
   <updated>2017-12-07T00:00:00+00:00</updated>
   <id>http://fruch.github.io/2017/12/07/microsoft-wsl-vscode</id>
   <content type="html">
&lt;h1 id=&quot;wsl&quot;&gt;WSL&lt;/h1&gt;

&lt;p&gt;I’ve took &lt;a href=&quot;https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux&quot;&gt;WSL&lt;/a&gt; for a spin today, and I’m impressed.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# doing something like this&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;docker.io
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Actully worked, i.e. installed. you can’t start the dockerd as failed as in &lt;a href=&quot;https://github.com/Microsoft/WSL/issues/2291&quot;&gt;#2291&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But you can use the docker client, and connect a server running dockerd (or in win10 pro the native docker supported)&lt;/p&gt;

&lt;p&gt;The direction is quite good, I can have tmux and my favorite nano working stright on my windows box like that.&lt;/p&gt;

&lt;p&gt;Still didn’t figured out how to leave things running, like my tmux session (if at all possible)&lt;/p&gt;

&lt;h1 id=&quot;vscode&quot;&gt;VSCode&lt;/h1&gt;

&lt;p&gt;Anthoer supprise from microsoft (I guess it’s not that new, just new to me), is &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VSCode&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hated visual studio for year, and this one is fully open source based on node.js, resembles more atom.&lt;/p&gt;

&lt;p&gt;List of goodies I have with it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;markdown previews&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;spellchecker&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;python pylint&lt;/strong&gt; - based on my config files, and not as in Pycharm own code style checks.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;node linting&lt;/strong&gt; - again working with my config (I guess WebStorm has it too, but it’s not free)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://plantuml.com/&quot;&gt;plantuml&lt;/a&gt; preview&lt;/strong&gt; - amazing for documention&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;terminal&lt;/strong&gt; can use gitbash inside of it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The marketplace of plugings, is also quite nice, and sits in a very front and center place (looking at you jetbrains, suggestion is nice, but getting to the list of plugin is a bit long)&lt;/p&gt;

&lt;p&gt;The updates are a bit more plesent then in Jetbrain products, and comes with great webcast on each major feature. (giving us a very good lesson on writing release notes :))&lt;/p&gt;

&lt;p&gt;And also people are pushing to have it running under WSL &lt;a href=&quot;https://github.com/Microsoft/WSL/issues/2293&quot;&gt;#2293&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;I see a very bright future for microsoft steping into the core thing that the development community are looking at.&lt;/p&gt;

&lt;p&gt;Microsoft, i’m keeping my ears and eyes open…&lt;/p&gt;

&lt;p&gt;You got my attention !&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>KISS - Keep it shorter short</title>
   <link href="http://fruch.github.io/2016/07/08/kiss-keep-it-shorter-short"/>
   <updated>2016-07-08T00:00:00+00:00</updated>
   <id>http://fruch.github.io/2016/07/08/kiss-keep-it-shorter-short</id>
   <content type="html">
&lt;p&gt;Today on work on a python related mailing list someone sent this snippet of code he didn’t wrote.
and that was causing some of the server he worte/manged some troubles.&lt;/p&gt;

&lt;p&gt;Here’s the code:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;deploy_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full_path_to_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_to_file&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_to_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;print_error_exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot; wrong input for deploy_file&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;post_status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full_path_to_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;rb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Deploying...:  %s&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;file_content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;post_status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status_code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status_code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;201&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status_code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;202&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Success:  %s&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;uploaded&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_to_upload&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;print_error_exit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Deployment to %s failed. status_code = %s, returned_text = %s&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;print_error_exit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Posting with url %s failed. status: %s&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;post_status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;First thought I hade was, the one wrote it is must be coming from C (or maybe Java), so let go over what’s wrong here.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Input validation&lt;/p&gt;

    &lt;p&gt;I don’t know what’s print_error_exit() is doing exactly, let’s assume it’s raising expection (hopefully it’s not calling os.exit())  &lt;br /&gt;
 So assertion with the proper text would be alsmot identical.&lt;/p&gt;

    &lt;p&gt;Checking both for None, and for empty string is futile, just assert, like this:&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;        &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_to_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parameter can't be empty&quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parameter can't be empty&quot;&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Using requests to stream file&lt;/p&gt;

    &lt;p&gt;Requests is cool, alsmot the defacto standard when HTTP client is need in python.
 it has very good documention, clearly someone didn’t read it.&lt;a href=&quot;http://docs.python-requests.org/en/master/user/advanced/#streaming-uploads&quot;&gt;streaming uploads&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Multiple error paths&lt;/p&gt;

    &lt;p&gt;Lot of different error handling code, one for checking the http statuses and one for catching expections.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;my-version&quot;&gt;My version&lt;/h1&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;deploy_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full_path_to_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_to_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parameter can't be empty&quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;parameter can't be empty&quot;&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full_path_to_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;rb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Deploying...:  %s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

                &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

                &lt;span class=&quot;k&quot;&gt;assert&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status_code&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;201&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;202&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Success:  %s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;uploaded&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file_to_upload&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;deploy_file faild&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# so we'll have a nice print in the log
&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# casue I don't know what print_error_exit() does, we'll call it.
&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# even that I would prefer to just raise the expection up, i.e. &quot;raise ex&quot;
&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;print_error_exit&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Deployment to %s failed. status_code = %s, returned_text = %s&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; 
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full_path_in_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;status_code&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</content>
 </entry>
 
 <entry>
   <title>Microsoft + Docker, really ?</title>
   <link href="http://fruch.github.io/2014/11/09/microsoft-docker-really"/>
   <updated>2014-11-09T00:00:00+00:00</updated>
   <id>http://fruch.github.io/2014/11/09/microsoft--docker-really-</id>
   <content type="html">
&lt;p&gt;Today &lt;a href=&quot;http://weblogs.asp.net/scottgu/docker-and-microsoft-integrating-docker-with-windows-server-and-microsoft-azure&quot;&gt;this&lt;/a&gt; blog post of Scott Guthrie from Microsoft was slash-dotted.
Interesting enough, I had no idea one can actually run Docker on Windows, got me to find that there’s an &lt;a href=&quot;https://docs.docker.com/installation/windows/&quot;&gt;installer&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;From the details, I couldn’t figure if that’s mean we could actually spin a windows docker host, and run linux based dockerized apps ?
even if it’s intended only for running windows based dockerized apps, it’s an interesting match which I think I’ll might find handy in the future.&lt;/p&gt;

&lt;p&gt;Docker is really interesting, but it got a very weird edges. 3 examples:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;When your host is 64bit, and you need a 32bit application. it’s not that easy to setup up, I’ve tried couple of time and failed.&lt;/li&gt;
  &lt;li&gt;Anther weird stuff I’ve run into was this &lt;a href=&quot;https://github.com/docker/docker/issues/2267&quot;&gt;issue&lt;/a&gt;, (don’t ask why I need to manually change /etc/hosts, It’s a sad answer) but some kind of limitations are in place, and might drive away arguing things like “Change hosts and resolv is the basic operation in daily working.”&lt;/li&gt;
  &lt;li&gt;Entering a docker you’ve created, C`mon is should be a bit easier and integrated into docker (and not that long command line to remember)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Anyhow the whole experience with docker is very nice, and I do recommend giving it a spin. (you’ll sure put this one in your toolbox/toolbelt)&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Taming the logging formatter</title>
   <link href="http://fruch.github.io/2014/11/06/taming-the-logging-formatter"/>
   <updated>2014-11-06T00:00:00+00:00</updated>
   <id>http://fruch.github.io/2014/11/06/taming-the-logging-formatter</id>
   <content type="html">
&lt;p&gt;We love logging, and we use it all around our code. (it’s the standard/built-in/batteries included)&lt;/p&gt;

&lt;p&gt;We have those hugh json objects flying around, we want to log them.&lt;/p&gt;

&lt;p&gt;pprint.pformat comes handy for those cases:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pprint&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;my_large_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my large inforamtion&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;dicts, dicts, dicts,&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;??&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;***&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
                  &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my large inforamtion&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;how we love big dicts ?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;??&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;***&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
                  &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my large inforamtion&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;how we love big dicts ? don't we ?,&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;???&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;***&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Mary &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; had &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; a &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; little &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; lamb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pformat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_large_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pformat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_large_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;but when used with complex formatter the output goes like that:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;^14/11/06 00:58:39 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:74 &amp;gt; Mary
 had
 a
 little
 lamb
^14/11/06 00:58:39 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:75 &amp;gt; [{'data': 'my large inforamtion',
  'data1': 'dicts, dicts, dicts,',
  'data3': {'a': '??', 'b': 2, 'c': 3, 'd': '***'}},
 {'data': 'my large inforamtion',
  'data1': 'how we love big dicts ?',
  'data3': {'a': '??', 'b': 2, 'c': 3, 'd': '***'}},
 {'data': 'my large inforamtion',
  'data1': &quot;how we love big dicts ? don't we ?,&quot;,
  'data3': {'a': '???', 'b': 2, 'c': 3, 'd': '***'}}]
^14/11/06 00:58:39 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:76 &amp;gt; [{'data': 'my large inforamtion',
  'data1': 'dicts, dicts, dicts,',
  'data3': {'a': '??', 'b': 2, 'c': 3, 'd': '***'}},
 {'data': 'my large inforamtion',
  'data1': 'how we love big dicts ?',
  'data3': {'a': '??', 'b': 2, 'c': 3, 'd': '***'}},
 {'data': 'my large inforamtion',
  'data1': &quot;how we love big dicts ? don't we ?,&quot;,
  'data3': {'a': '???', 'b': 2, 'c': 3, 'd': '***'}}]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Kinda, not really helpful:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;em&gt;confusing&lt;/em&gt; - and you loose track of where this print came from really fast (keep in mind I’m talking about humongous json object)&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;filtering&lt;/em&gt; is (almost) impossible (yeah, not without some extra regex kung-fu)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Skimmed through the logging documentations, google it a bit think someone already solved those things
and I could copy paste, came out empty handed.&lt;/p&gt;

&lt;p&gt;So here how it can be fixed:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;logging&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MultiLineFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Formatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
        split the message into different line and prepend it with the formatting
        :param record:
        :return: the formatted string
        &quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;usesTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;asctime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;formatTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datefmt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__dict__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'message'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_fmt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# Cache the traceback text to avoid converting it multiple times
&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# (it's constant anyway)
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;formatException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_text&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;UnicodeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;# Sometimes filenames have non-ASCII chars, which can lead
&lt;/span&gt;                &lt;span class=&quot;c1&quot;&gt;# to errors when s is Unicode and record.exc_text is str
&lt;/span&gt;                &lt;span class=&quot;c1&quot;&gt;# See issue 8924.
&lt;/span&gt;                &lt;span class=&quot;c1&quot;&gt;# We also use replace for when there are multiple
&lt;/span&gt;                &lt;span class=&quot;c1&quot;&gt;# encodings, e.g. UTF-8 for the filesystem and latin-1
&lt;/span&gt;                &lt;span class=&quot;c1&quot;&gt;# for a script. See issue 13232.
&lt;/span&gt;                &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getfilesystemencoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                                               &lt;span class=&quot;s&quot;&gt;'replace'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# and two examples how to configure the root logger to use it
&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;logging&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;logging.config&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;basicConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;configure_with_api&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StreamHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;formatter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MultilineFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'^%(asctime)s !%(levelname)s &amp;lt;t:%(threadName)s T:%(name)s M:%(filename)s F:%(funcName)s L:%(lineno)d &amp;gt; %(message)s'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                  &lt;span class=&quot;n&quot;&gt;datefmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'%y/%m/%d %H:%M:%S'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;formatter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;formatter&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;configure_with_dictConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dictConfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'version'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'disable_existing_loggers'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'formatters'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;'multiline'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;'()'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MultilineFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;'format'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'^%(asctime)s !%(levelname)s &amp;lt;t:%(threadName)s T:%(name)s M:%(filename)s F:%(funcName)s L:%(lineno)d &amp;gt; %(message)s'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;'datefmt'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'%y/%m/%d %H:%M:%S'&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'handlers'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;'console'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:{&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;'class'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'logging.StreamHandler'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;'formatter'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'multiline'&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;'loggers'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;'handlers'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'console'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;'propagate'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;'level'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'INFO'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;and now our output is much much clearer:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:74 &amp;gt; Mary
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:74 &amp;gt;  had
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:74 &amp;gt;  a
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:74 &amp;gt;  little
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:74 &amp;gt;  lamb
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:75 &amp;gt; [{'data': 'my large inforamtion',
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:75 &amp;gt;   'data1': 'dicts, dicts, dicts,',
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:75 &amp;gt;   'data3': {'a': '??', 'b': 2, 'c': 3, 'd': '***'}},
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:75 &amp;gt;  {'data': 'my large inforamtion',
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:75 &amp;gt;   'data1': 'how we love big dicts ?',
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:75 &amp;gt;   'data3': {'a': '??', 'b': 2, 'c': 3, 'd': '***'}},
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:75 &amp;gt;  {'data': 'my large inforamtion',
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:75 &amp;gt;   'data1': &quot;how we love big dicts ? don't we ?,&quot;,
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:75 &amp;gt;   'data3': {'a': '???', 'b': 2, 'c': 3, 'd': '***'}}]
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:76 &amp;gt; [{'data': 'my large inforamtion',
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:76 &amp;gt;   'data1': 'dicts, dicts, dicts,',
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:76 &amp;gt;   'data3': {'a': '??', 'b': 2, 'c': 3, 'd': '***'}},
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:76 &amp;gt;  {'data': 'my large inforamtion',
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:76 &amp;gt;   'data1': 'how we love big dicts ?',
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:76 &amp;gt;   'data3': {'a': '??', 'b': 2, 'c': 3, 'd': '***'}},
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:76 &amp;gt;  {'data': 'my large inforamtion',
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:76 &amp;gt;   'data1': &quot;how we love big dicts ? don't we ?,&quot;,
^14/11/06 00:54:51 !ERROR &amp;lt;t:MainThread T:root M:log.py F:&amp;lt;module&amp;gt; L:76 &amp;gt;   'data3': {'a': '???', 'b': 2, 'c': 3, 'd': '***'}}]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer: use with caution, written past midnight :)&lt;/strong&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>ELK is fun</title>
   <link href="http://fruch.github.io/blog/2014/10/30/ELK-is-fun"/>
   <updated>2014-10-30T00:00:00+00:00</updated>
   <id>http://fruch.github.io/blog/2014/10/30/ELK-is-fun</id>
   <content type="html">
&lt;p&gt;As I do a lot of testing and CI in my day job, I took ELK for a test drive.
(ELK stands for &lt;a href=&quot;http://www.elasticsearch.org/overview/elasticsearch/&quot;&gt;ElasticSearch&lt;/a&gt;, &lt;a href=&quot;http://www.elasticsearch.org/overview/logstash/&quot;&gt;LogStash&lt;/a&gt; and &lt;a href=&quot;http://www.elasticsearch.org/overview/kibana/&quot;&gt;Kibana&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;I’ve played around with Logstash before, but it’s first time i’m trying Kibana.&lt;/p&gt;

&lt;p&gt;I’ve look for a quick way to setup it, and there where gazillion hits in &lt;a href=&quot;https://registry.hub.docker.com/search?&amp;amp;q=elk&quot;&gt;Docker Hub&lt;/a&gt;
(I’ve forgot which one I’ve actually installed :))
&lt;em&gt;EDIT:&lt;/em&gt; it was cyberabis/docker-elkauto.&lt;/p&gt;

&lt;p&gt;That went quick quickly, with a small change that I’ve used port 81&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://fruch.github.io/assets/img/ELK.jpg&quot;&gt;&lt;img src=&quot;http://fruch.github.io/assets/img/ELK.jpg&quot; width=&quot;380&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next thing I wanted to feed it with some data, good thing someone else added some key=value files to our CI just a few days ago (Thanks Mike).
And I had first real data in to play with in matter of minutes&lt;/p&gt;

&lt;p&gt;That’s was not enough for me, I wanted all the information from my tests.
Seem like the junit-xml output has all the information I wanted.
I hated the idea of running something after the tests are running,
I wanted it to run automatic on any test I’ll run with py.test.&lt;/p&gt;

&lt;p&gt;Took me some time to figure it out which py.test hook fits the best, and here’s how it can be done:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;c1&quot;&gt;# content of conftest.py
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;collect_ec_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
        if we run in EC, collect all data we need
        if not in EC, collect only commit and commit_sha
        :return: dict
        &quot;&quot;&quot;&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# lets assume you don't really want to know what we save in our setup :)
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_collected&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;send_to_elk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
        send `item` to Logstash port
        :param item: dict
        :return: None
        &quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AF_INET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SOCK_STREAM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TCP_IP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TCP_PORT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Sending to %s:%d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TCP_IP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TCP_PORT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sendall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dumps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;find_test_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;junit_xml_filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;
        flatten all the data from junit based xml file into a list of dicts

        :param junit_xml_filename: the output from py.test --junit-xml
        :return:
        &quot;&quot;&quot;&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;tests_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;xml_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;junit_xml_filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'r'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;et&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ElementTree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromstring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xml_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;et&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'testcase'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attrib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;outcome&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;failure&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;failure&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;skipped&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;skipped&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;failure&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'failure_message'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;failure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;outcome&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'failure'&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;skipped&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'skip_message'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;skipped&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attrib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'message'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;outcome&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'skipped'&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'error_message'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;outcome&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'error'&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;outcome&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'success'&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'outcome'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outcome&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'run_time'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'time'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;# time is a built in in Logstash
&lt;/span&gt;            &lt;span class=&quot;k&quot;&gt;del&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'time'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;tests_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;# filter by group, and merge result
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;cumulative_keys&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'outcome'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'run_time'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tests_list_grouped&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tests_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'classname'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thing&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;# merge needed values
&lt;/span&gt;                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'outcome'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'outcome'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &amp;amp; &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'outcome'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'run_time'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'run_time'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'run_time'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

                &lt;span class=&quot;c1&quot;&gt;# overwrite the rest
&lt;/span&gt;                &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cumulative_keys&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;tests_list_grouped&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tests_list_grouped&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pytest_unconfigure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;junit_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pytest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xmlpath&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ec_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;collect_ec_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;log_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;environ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'LOG_DEST_DIR'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'./'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;junit_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# if found xml file, send all of it
&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;tests_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;find_test_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;junit_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tests_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ec_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

                &lt;span class=&quot;c1&quot;&gt;# save data to a file
&lt;/span&gt;                &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'job_info%d.json'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'w+'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dumps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sort_keys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                       &lt;span class=&quot;n&quot;&gt;indent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;separators&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;','&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;': '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;

                &lt;span class=&quot;n&quot;&gt;send_to_elk&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Just for reference, to show how simple is the logstash configuration, almost untouched:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;input {
        tcp { port =&amp;gt; 3333 type =&amp;gt; &quot;text event&quot;}
        tcp { port =&amp;gt; 3334 type =&amp;gt; &quot;json event&quot; codec =&amp;gt; json_lines {} }
}
filter {
        if [createTime] {
                date {
                        match =&amp;gt; [ &quot;createTime&quot;, &quot;ISO8601&quot; ]
                        target =&amp;gt; &quot;@timestamp&quot;
                }
        }

}
output { elasticsearch { host =&amp;gt; localhost } }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;ELK is a great combo, me like a lot…&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>TheLinuxGameTome is dying, lets save it</title>
   <link href="http://fruch.github.io/blog/2013/04/05/saving-a-linux-happy-peguin"/>
   <updated>2013-04-05T00:00:00+00:00</updated>
   <id>http://fruch.github.io/blog/2013/04/05/saving-a-linux-happy-peguin</id>
   <content type="html">
&lt;p&gt;I’ve read this story on &lt;a href=&quot;http://linux.slashdot.org/story/13/03/26/065223/the-end-is-nigh-for-the-linux-game-tome&quot;&gt;Slashdot&lt;/a&gt;, and thought I might take the database as a django practice build a real web site.
Who want to join me ?&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>keeping code clean (the way of the nazi)</title>
   <link href="http://fruch.github.io/blog/2012/06/15/keeping-code-clean-the-way-of-the-nazi"/>
   <updated>2012-06-15T00:00:00+00:00</updated>
   <id>http://fruch.github.io/blog/2012/06/15/keeping-code-clean-the-way-of-the-nazi</id>
   <content type="html">
&lt;p&gt;Reading some comments in &lt;a href=&quot;http://www.blog.pythonlibrary.org/2011/01/26/pychecker-python-code-analysis/&quot;&gt;Mouse vs Python&lt;/a&gt;,
I’ve enounter this gem &lt;a href=&quot;http://github.com/storborg/pep8nazi&quot;&gt;pep8nazi&lt;/a&gt;,
that can help in not lettig any code that doesn’t comply to pep8 to run at all&lt;/p&gt;

&lt;p&gt;really like the idea, question is how it will work in real life scenrio when the package you’ll use
aren’t fully complient to pep8.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Tools, tools, tools</title>
   <link href="http://fruch.github.io/2012/04/09/tools-tools-tools"/>
   <updated>2012-04-09T00:00:00+00:00</updated>
   <id>http://fruch.github.io/2012/04/09/tools-tools-tools</id>
   <content type="html">
&lt;p&gt;People always complain about tools, me included.
(a.k.a trying to show that their own tool set are better)
from text-editor to IDE, and don’t get me starting on usability of some websites…&lt;/p&gt;

&lt;p&gt;This guy took it a further and kind of made it into a life philosophy
&lt;a href=&quot;http://vimeo.com/36579366&quot;&gt;Bret Victor - Inventing on Principle&lt;/a&gt;. and kinda of proved that all our tools suck.
Really liked the tools he demonstrated, especially the mario like demo.&lt;/p&gt;

&lt;p&gt;BTW, his site is kinda of cool &lt;a href=&quot;http://worrydream.com/&quot;&gt;http://worrydream.com/&lt;/a&gt;
and I quote from there:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;“I designed the initial user interface concepts for iPad, iPod Nano, and half a
dozen  experimental  hardware  platforms.  Initiated,  designed,  and  prototyped  over
seventy concept projects…”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;sound like a dream job.&lt;/p&gt;

&lt;p&gt;and now it got me thinking, do I have a principle ? (or do I need one to get such a dream job ?)&lt;/p&gt;

&lt;p&gt;probably not… or at least not yet… but I guess I’m getting there.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Why we HATE writting plans?</title>
   <link href="http://fruch.github.io/blog/2012/03/29/why-we-hate-writing-plans"/>
   <updated>2012-03-29T00:00:00+00:00</updated>
   <id>http://fruch.github.io/blog/2012/03/29/why-we-hate-writing-plans</id>
   <content type="html">
&lt;p&gt;Every time I need to start working on planning documentation,
I get this weird feeling that I’m wasting my time.&lt;/p&gt;

&lt;p&gt;I’ve tried to scribe down the reasons:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Nobody is going to read it, so why actually putting so much work into it ?&lt;/li&gt;
  &lt;li&gt;things are bound to change, so it isn’t worth the paper it’s written on (paper as in bytes on my hard-drive)&lt;/li&gt;
  &lt;li&gt;I know that I won’t have time/manpower to actually do 20% of what I’m going to plan, so what the use ?&lt;/li&gt;
  &lt;li&gt;My English sucks, no one will understand what I’m writing&lt;/li&gt;
  &lt;li&gt;I never seen a good plan, that actually succeeded. So there’s no good plans…&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now I’m left with tackling each one, and trying to hack my brain into thinking it would be fun to write the plan…&lt;/p&gt;

&lt;p&gt;Coming up next in “Fruch picking his brain”…&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Highlights from pyvideo.org</title>
   <link href="http://fruch.github.io/blog/2012/03/29/highlights-from-pyvideoorg"/>
   <updated>2012-03-29T00:00:00+00:00</updated>
   <id>http://fruch.github.io/blog/2012/03/29/highlights-from-pyvideoorg</id>
   <content type="html">
&lt;p&gt;Look like people were quite busy in the latest &lt;a href=&quot;https://us.pycon.org/2012/&quot;&gt;US PyCon&lt;/a&gt;,
I need to promise myself to actually attend one in the next coming years.
too bad there no such thing in IL, to only closest thing is the meetups of &lt;a href=&quot;https://groups.google.com/forum/?fromgroups#!forum/pyweb-il&quot;&gt;PyWeb-IL&lt;/a&gt;
(I want to attend one also…, even thought on trying to host one at my day job office)&lt;/p&gt;

&lt;p&gt;So thanks to the people of &lt;a href=&quot;http://pyvideo.org/&quot;&gt;pyvideo.org&lt;/a&gt;, we could actually see what was going on.&lt;/p&gt;

&lt;h1 id=&quot;frozen-yogort&quot;&gt;Frozen Yogort&lt;/h1&gt;

&lt;p&gt;I’ve seen “&lt;a href=&quot;http://pyvideo.org/video/470/pyconau-2010--esky--keep-your-frozen-apps-fresh&quot;&gt;Esky: keep your frozen apps fresh&lt;/a&gt;”, this guy really touch the spot,
on how to deliver the code to mortal that can’t handle the python interpeter.&lt;/p&gt;

&lt;p&gt;Amazing how it can be done with three line of code (yes, and anthor two in the &lt;em&gt;setup.py&lt;/em&gt;):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;frozen&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;esky&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Esky&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;executable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://example.com/downloads/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;auto_update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;go fetch it from PyPi, &lt;em&gt;&lt;a href=&quot;http://pypi.python.org/pypi/esky/&quot;&gt;esky&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;restful-apis-for-the-tired&quot;&gt;RESTful APIs for the tired&lt;/h2&gt;

&lt;p&gt;In &lt;a href=&quot;http://pyvideo.org/video/90/djangocon-2011--building-apis-in-django-with-tast&quot;&gt;this One&lt;/a&gt;,
it show how easy is to add RESTful API to a django application.&lt;/p&gt;

&lt;p&gt;Very useful if you want to keep those control freaks nerds happy,
now they could write a bash script that uses curl to interact with your site.&lt;/p&gt;

&lt;h2 id=&quot;fast-test-slow-test&quot;&gt;Fast Test, Slow Test&lt;/h2&gt;

&lt;p&gt;And a one about testing, casue my job title dictates it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://pyvideo.org/video/631/fast-test-slow-test&quot;&gt;Fast Test, Slow Test&lt;/a&gt;, by &lt;a href=&quot;https://github.com/garybernhardt&quot;&gt;Gary Bernhardt&lt;/a&gt;
(really liked his &lt;a href=&quot;https://github.com/garybernhardt/dotfiles&quot;&gt;dotfiles&lt;/a&gt; repo)&lt;/p&gt;

&lt;p&gt;I really agreed with almost every word he were saying, too bad it really is a pain actully writing unittests that hit the right spots.
his saying about not writing tests to “bake” the bad desgin into the system, reminded me what i’m doing almost daily. Writing tests to match requirements or other system behivers that are actully wrong or will do more bad then good in the system.&lt;/p&gt;

&lt;p&gt;But then, who has to power/will to change a big eco system upside down ?&lt;/p&gt;

&lt;p&gt;Think of it, one of the tester that work at Microsoft on a new version of Windows,
will come and say that the briliant people who thought and desgin something we’re wrong.
He will probably give up, every before that thought will touch the first neuron in his brain…&lt;/p&gt;

&lt;p&gt;We all want to come home in one piece ( &lt;a href=&quot;http://www.givathatachmoshet.org.il/songs.php?song=song1.flv&quot;&gt;בסך הכל רציתי לחזור הביתה בשלום&lt;/a&gt;)&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Hello World</title>
   <link href="http://fruch.github.io/blog/2012/03/29/hello-world"/>
   <updated>2012-03-29T00:00:00+00:00</updated>
   <id>http://fruch.github.io/blog/2012/03/29/hello-world</id>
   <content type="html">
&lt;p&gt;So I’ve started a blog.&lt;/p&gt;

&lt;p&gt;First thanks, to &lt;a href=&quot;http://jekyllbootstrap.com/&quot;&gt;JekyllBootstrap&lt;/a&gt; for the code, 
and for &lt;a href=&quot;http://github.com/&quot;&gt;Github&lt;/a&gt; for the hosting (כבודה של אכסניה)&lt;/p&gt;

&lt;p&gt;Even that I uselly don’t use ruby, I’ve installed it on my win7 for running jekyll.
thanks god no need to actully code in ruby for that.&lt;/p&gt;

&lt;p&gt;I hope now I can actully share some of my insights about python and life in general.
(after I fooled around a whole day on choosing the theme, and adding facebook comments)&lt;/p&gt;

&lt;p&gt;I wish myself that I’ll find time to write.&lt;/p&gt;

&lt;p&gt;Fruch out…&lt;/p&gt;
</content>
 </entry>
 
 
</feed>