Skip to main content
  1. All Posts/

log4brains

Tools TypeScript

Log4brains

Log4brains is a docs-as-code knowledge base for your development and infrastructure projects.
It enables you to log Architecture Decision Records (ADR) right from your IDE and to publish them automatically as a static website.
By logging your decisions chronologically, you will be able to:

  • Understand past technical decisions and their context
  • Take new decisions with confidence
  • Always have a up-to-date technical documentation and training material available
  • Onboard new developers quicker
  • Set up a collaborative decision process thanks to pull requests

Features

  • Docs-as-code: ADRs are written in markdown, stored in your git repository, close to your code
  • Local preview with Hot Reload
  • Interactive ADR creation from the CLI
  • Static site generation to publish to GitHub/GitLab Pages or S3
  • Timeline menu
  • Searchable
  • ADR metadata automatically guessed from its raw text and git logs
  • No enforced markdown structure: you are free to write however you want
  • No required file numbering schema (i.e., adr-0001.md, adr-0002.md…): avoids git merge issues
  • Customizable template (default: MADR)
  • Multi-package projects support (mono or multi repo): notion of global and package-specific ADRs

Coming soon:

  • Local images and diagrams support
  • RSS feed to be notified of new ADRs
  • Decision backlog
  • @adr annotation to include code references in ADRs
  • ADR creation/edition from the UI
  • Create a new GitHub/GitLab issue from the UI
  • … let’s suggest a new feature if you have other needs!

<p>
  </a>
</p>

<p>
  <a rel="nofollow noopener" target="_blank" href="https://www.youtube.com/watch?v=HDEwOCn9T0w">🎞️ Watch the full screencast</a> &#8211; <a rel="nofollow noopener" target="_blank" href="https://thomvaill.github.io/log4brains/adr/">⚡ See an example (Log4brains&#8217; own ADRs)</a>
</p>

<h2 dir="auto">
  <a rel="nofollow noopener" target="_blank" id="user-content-table-of-contents-" class="anchor" aria-hidden="true" href="#table-of-contents-"></a>Table of contents
</h2>

<ul dir="auto">
  <li>
    <a rel="nofollow noopener" target="_blank" href="#-getting-started">🚀 Getting started</a>
  </li>
  <li>
    <a rel="nofollow noopener" target="_blank" href="#-what-is-an-adr-and-why-should-you-use-them">🤔 What is an ADR and why should you use them</a>
  </li>
  <li>
    <a rel="nofollow noopener" target="_blank" href="#-cicd-configuration-examples">📨 CI/CD configuration examples</a>
  </li>
  <li>
    <a rel="nofollow noopener" target="_blank" href="#-faq">❓ FAQ</a></p> <ul dir="auto">
      <li>
        <a rel="nofollow noopener" target="_blank" href="#what-are-the-prerequisites">What are the prerequisites?</a>
      </li>
      <li>
        <a rel="nofollow noopener" target="_blank" href="#is-log4brains-only-for-js-projects">Is Log4brains only for JS projects?</a>
      </li>
      <li>
        <a rel="nofollow noopener" target="_blank" href="#what-about-multi-package-projects">What about multi-package projects?</a>
      </li>
      <li>
        <a rel="nofollow noopener" target="_blank" href="#how-to-configure-log4brainsyml">How to configure <code>.log4brains.yml</code>?</a>
      </li>
      <li>
        <a rel="nofollow noopener" target="_blank" href="#is-log4brains-also-available-as-a-docker-image">Is Log4brains also available as a Docker image?</a>
      </li>
    </ul>
  </li>
  
  <li>
    <a rel="nofollow noopener" target="_blank" href="#-your-feedback-is-welcome">📣 Your feedback is welcome!</a>
  </li>
  <li>
    <a rel="nofollow noopener" target="_blank" href="#contributing">Contributing</a>
  </li>
  <li>
    <a rel="nofollow noopener" target="_blank" href="#acknowledgments">Acknowledgments</a>
  </li>
  <li>
    <a rel="nofollow noopener" target="_blank" href="#license">License</a>
  </li>
</ul>

<h2 dir="auto">
  <a rel="nofollow noopener" target="_blank" id="user-content--getting-started" class="anchor" aria-hidden="true" href="#-getting-started"></a>🚀 Getting started
</h2>

<p>
  We recommend storing your Architecture Decision Records (ADR) next to the source code of your project,<br /> in the same git repository, to keep them in sync.<br /> To get started, run these commands inside your project root folder:
</p>

<pre>npm install -g log4brains

log4brains init

<p>
  It will ask you several questions to get Log4brains properly configured. It will also create the required template files and your first ADR as well.<br /> Then, you can start the web UI to preview your knowledge base locally:
</p>

<pre>log4brains preview</pre>

<p>
  In this mode, the Hot Reload feature is enabled: any change<br /> you make to a markdown file from your IDE is applied live.<br /> To create a new ADR from your template, run this command:
</p>

<pre>log4brains adr new</pre>

<p>
  Get all the available commands and options by running <code>log4brains --help</code>.<br /> Finally, do not forget to <a rel="nofollow noopener" target="_blank" href="#-cicd-configuration-examples">set up your CI/CD pipeline</a> to automatically publish your knowledge base on a static website service like GitHub/GitLab Pages or S3.
</p>

<h2 dir="auto">
  <a rel="nofollow noopener" target="_blank" id="user-content--what-is-an-adr-and-why-should-you-use-them" class="anchor" aria-hidden="true" href="#-what-is-an-adr-and-why-should-you-use-them"></a>🤔 What is an ADR and why should you use them
</h2>

<p>
  The term ADR became popular in 2011 with Michael Nygard&#8217;s article: <a rel="nofollow noopener" target="_blank" href="https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions">documenting architecture decisions</a>. He aimed to reconcile Agile methods with software documentation by creating a very concise template<br /> to record functional or non-functional &#8220;architecturally significant&#8221; decisions in a lightweight format like markdown.<br /> The original template had only a few parts:
</p>

<ul dir="auto">
  <li>
    <strong>Title</strong>: Which sums up the solved problem and its solution
  </li>
  <li>
    <strong>Context</strong>: Probably the essential part, which describes &#8220;the forces at play, including technological, political, social, and project local&#8221;
  </li>
  <li>
    <strong>Decision</strong>
  </li>
  <li>
    <strong>Status</strong>: Proposed, accepted, deprecated, superseded&#8230;
  </li>
  <li>
    <strong>Consequences</strong>: The positive and negative ones for the future of the project
  </li>
</ul>

<p>
  There are other ADR templates like <a rel="nofollow noopener" target="_blank" href="https://medium.com/olzzio/y-statements-10eb07b5a177">Y-Statements</a> or <a rel="nofollow noopener" target="_blank" href="https://adr.github.io/madr/">MADR</a>, which is the default one that is shipped with Log4brains.<br /> As you can guess from the template above, an ADR is immutable. Only its status can change.<br /> Thanks to this, your documentation is never out-of-date! Yes, an ADR can be deprecated or superseded by another one, but it was at least true one day!<br /> And even if it&#8217;s not the case anymore, it is still a precious piece of information.<br /> This leads us to the main goals of this methodology:
</p>

<ul dir="auto">
  <li>
    Avoid blind acceptance and blind reversal when you face past decisions
  </li>
  <li>
    Speed up the onboarding of new developers on a project
  </li>
  <li>
    Formalize a collaborative decision-making process
  </li>
</ul>

<p>
  To learn more on this topic, I recommend you to read these great resources:
</p>

<ul dir="auto">
  <li>
    <a rel="nofollow noopener" target="_blank" href="https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions">Documenting architecture decisions</a>, by Michael Nygard
  </li>
  <li>
    <a rel="nofollow noopener" target="_blank" href="https://adr.github.io/">ADR GitHub organization</a>, home of the <a rel="nofollow noopener" target="_blank" href="https://adr.github.io/madr/">MADR</a> template, by Oliver Kopp and <a rel="nofollow noopener" target="_blank" href="https://ozimmer.ch/">Olaf Zimmermann</a>
  </li>
  <li>
    Collection of ADR templates and examples by Joel Parker Henderson
  </li>
</ul>

<h2 dir="auto">
  <a rel="nofollow noopener" target="_blank" id="user-content--cicd-configuration-examples" class="anchor" aria-hidden="true" href="#-cicd-configuration-examples"></a>📨 CI/CD configuration examples
</h2>

<p>
  Log4brains lets you publish automatically your knowledge base on the static hosting service of your choice, thanks to the <code>log4brains-web build</code> command.<br /> Here are some configuration examples for the most common hosting services / CI runners.
</p>

<p>
  Publish to GitHub Pages with GitHub Actions
</p>

<p>
  First, create <code>.github/workflows/publish-log4brains.yml</code> and adapt it to your case:
</p>

<pre>name: Publish Log4brains

on: push: branches: - master jobs: build-and-publish: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2.3.4 with: persist-credentials: false # required by JamesIves/github-pages-deploy-action fetch-depth: 0 # required by Log4brains to work correctly (needs the whole Git history) - name: Install Node uses: actions/setup-node@v1 with: node-version: “14” - name: Install and Build Log4brains run: | npm install -g log4brains log4brains build –basePath /${GITHUB_REPOSITORY#*/}/log4brains - name: Deploy uses: JamesIves/github-pages-deploy-action@3.7.1 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} BRANCH: gh-pages FOLDER: .log4brains/out TARGET_FOLDER: log4brains

<p>
  After the first run, this workflow will create a <code>gh-pages</code> branch in your repository containing the generated static files to serve.<br /> Then, we have to tell GitHub that we don&#8217;t want to use Jekyll, otherwise, you will get a 404 error:
</p>

<pre>git checkout gh-pages

touch .nojekyll git add .nojekyll git commit -m “Add .nojekyll for Log4brains” git push

<p>
  Finally, you can enable your GitHub page:
</p>

<ul dir="auto">
  <li>
    On GitHub, go to <code>Settings &gt; GitHub Pages</code>
  </li>
  <li>
    Select the <code>gh-pages</code> branch as the &#8220;Source&#8221;
  </li>
  <li>
    Then, select the <code>/ (root)</code> folder
  </li>
</ul>

<p>
  You should now be able to see your knowledge base at <code>https://&lt;username&gt;.github.io/&lt;repository&gt;/log4brains/</code>.<br /> It will be re-built and published every time you push on <code>master</code>.
</p>

<p>
  Publish to GitLab Pages with GitLab CI
</p>

<p>
  Create your <code>.gitlab-ci.yml</code> and adapt it to your case:
</p>

<pre>image: node:14-alpine3.12

pages: stage: deploy variables: GIT_DEPTH: 0 # required by Log4brains to work correctly (needs the whole Git history) script: - mkdir -p public - npm install -g –unsafe-perm log4brains - log4brains build –basePath /$CI_PROJECT_NAME/log4brains –out public/log4brains artifacts: paths: - public rules: - if: “$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH”

<p>
  You should now be able to see your knowledge base at <code>https://&lt;username&gt;.gitlab.io/&lt;repository&gt;/log4brains/</code>.<br /> It will be re-built and published every time you push on <code>master</code>.
</p>

<p>
  Publish to S3
</p>

<p>
  First, create a bucket with the &#8220;Static website hosting&#8221; feature enabled:
</p>

<pre># This is an example: replace with the bucket name of your choice

export BUCKET_NAME=yourcompany-yourproject-log4brains

aws s3api create-bucket –acl public-read –bucket ${BUCKET_NAME} read -r -d ’’ BUCKET_POLICY << EOP { “Statement”: [ { “Effect”: “Allow”, “Principal”: “”, “Action”: “s3:GetObject”, “Resource”: “arn:aws:s3:::${BUCKET_NAME}/” } ] } EOP aws s3api put-bucket-policy –bucket ${BUCKET_NAME} –policy “$BUCKET_POLICY” aws s3 website s3://${BUCKET_NAME} –index-document index.html

<p>
  Then, configure your CI to run these commands:
</p>

<ul dir="auto">
  <li>
    Install Node and the AWS CLI
  </li>
  <li>
    Checkout your Git repository <strong>with the full history</strong>. Otherwise, Log4brains won&#8217;t work correctly (see previous examples)
  </li>
  <li>
    <code>npm install -g log4brains</code>
  </li>
  <li>
    <code>log4brains build</code>
  </li>
  <li>
    <code>aws s3 sync .log4brains/out s3://&lt;YOUR BUCKET&gt; --delete</code>
  </li>
</ul>

<p>
  Your knowledge base will be available on <code>http://&lt;YOUR BUCKET&gt;.s3-website-&lt;YOUR REGION&gt;.amazonaws.com/</code>.<br /> You can get some inspiration on implementing this workflow for GitHub Actions or GitLab CI by looking at the previous examples.
</p>

<p>
  Finally, you can add the ADR badge to your <code>README.md</code>!
</p>

<p>
  <a rel="nofollow noopener" target="_blank" href="https://thomvaill.github.io/log4brains/adr/"></a><br /> <code>[![Log4brains ADRs](http://URL-of-your-knowledge-base/badge.svg)](http://URL-of-your-knowledge-base/)</code>
</p>

<h2 dir="auto">
  <a rel="nofollow noopener" target="_blank" id="user-content--faq" class="anchor" aria-hidden="true" href="#-faq"></a>❓ FAQ
</h2>

<h3 dir="auto">
  <a rel="nofollow noopener" target="_blank" id="user-content-what-are-the-prerequisites" class="anchor" aria-hidden="true" href="#what-are-the-prerequisites"></a>What are the prerequisites?
</h3>

<ul dir="auto">
  <li>
    Node.js >= 12
  </li>
  <li>
    NPM or Yarn
  </li>
  <li>
    Git
  </li>
</ul>

<h3 dir="auto">
  <a rel="nofollow noopener" target="_blank" id="user-content-is-log4brains-only-for-js-projects" class="anchor" aria-hidden="true" href="#is-log4brains-only-for-js-projects"></a>Is Log4brains only for JS projects?
</h3>

<p>
  Of course not! Log4brains is developed with TypeScript and use NPM as a package manager.<br /> You need Node and NPM to be installed globally to run Log4brains, but it is designed to work for all kind of projects.
</p>

<h3 dir="auto">
  <a rel="nofollow noopener" target="_blank" id="user-content-what-about-multi-package-projects" class="anchor" aria-hidden="true" href="#what-about-multi-package-projects"></a>What about multi-package projects?
</h3>

<p>
  Log4brains supports both mono and multi packages projects. The <code>log4brains init</code> command will prompt you regarding this.<br /> In the case of a multi-package project, you have two options:
</p>

<ul dir="auto">
  <li>
    Mono-repository: in this case, just install Log4brains in the root folder. It will manage &#8220;global ADRs&#8221;, for example in <code>docs/adr</code> and &#8220;package-specific ADRs&#8221;, for example in <code>packages/&lt;package name&gt;/docs/adr</code>.
  </li>
  <li>
    One repository per package: in the future, Log4brains will handle this case with a central repository for the &#8220;global ADRs&#8221; while fetching &#8220;package-specifics ADRs&#8221; directly from each package repository. For the moment, all the ADRs have to be stored in a central repository.
  </li>
</ul>

<p>
  Here is an example of a typical file structure for each case:
</p>

<p>
  Simple mono-package project
</p>

<pre class="notranslate"><code>project-root

├── docs | └── adr | ├── 20200101-your-first-adr.md | ├── 20200115-your-second-adr.md | ├── […] | ├── index.md | …