2021年2月: キッチンのレンジフードとガスコンロ 34万円
2020年5月:テレビ新調 85400円
2022年10月:畳の表替え 約10万円
2021年2月: キッチンのレンジフードとガスコンロ 34万円
2020年5月:テレビ新調 85400円
2022年10月:畳の表替え 約10万円
Grafanaを使って、自分の工数管理Webアプリのダッシュボードページにかっこいいパネルを並べる構想をしていたけど、この使いみちは厳しいということがわかったので諦める。
やっぱりPythonでやるしかないってことでグラフに関してはSeabornを確認して使っていくことで決心。
Excelのグラフ機能って偉大だな・・・
せっかくGrafanaを入れたので、色々Webを見ているとどうもサーバ監視とかに使うのが本流のツールのようなのでPrometheusとの連携をやってみる。
こちらのLinkを見てみると、Ubuntuの場合たった2行、ターミナルにaptコマンドを打ち込むだけでNode ExporterとPrometheusが導入できるそうな・・・。どれだけ簡単なんだ。
https://www.server-world.info/query?os=Ubuntu_20.04&p=prometheus&f=1
Node ExporterというのはどうもOSの各種統計情報を吐き出すツール、Prometheusはそれをためるツール、それをGrafanaでダッシュボードっぽく見やすくする、みたいな構成が多いらしい。
サーバリソースが見えるようになった。これ、今までこんな風にやったことなかったから少し感動だなあ。NextCloud + PhotoPrismの組み合わせってずっと変な処理動いてて重いような、疑ってたけど、そのへんよく見えるようになった。NextCloudのCron処理とかちょっと感覚空けて少なめにしてみた。
クラウドではなくSelf-Managed版を使う。Ubuntu 22.04に導入して動くところまでの確認と、どれくらいのサーバ負荷なのかを確認してみるところまでやってみたい。以前試したNextCloudとかPhotoPrismとかあんなレベルだとちょっときついけどどうだろう。
ここら辺にインストール方法が書いてあるけど、簡単そうだな・・・。メモるほどでもないかも。ただ、Editionの選択がEnterpriseではなくてOSSに変えてあげるところだけ忘れないようにする。
https://grafana.com/grafana/download?pg=get&plcmt=selfmanaged-box1-cta1&platform=linux
sudo apt-get install -y adduser libfontconfig1
wget https://dl.grafana.com/oss/release/grafana_9.2.0~beta1_amd64.deb
sudo dpkg -i grafana_9.2.0~beta1_amd64.deb
dpkgコマンドでインストールが完了し、以下がシェルにだらだらッと表示された。導線良くて助かるなあ。
Selecting previously unselected package grafana.
(Reading database ... 107757 files and directories currently installed.)
Preparing to unpack grafana_9.2.0~beta1_amd64.deb ...
Unpacking grafana (9.2.0~beta1) ...
Setting up grafana (9.2.0~beta1) ...
Adding system user `grafana' (UID 110) ...
Adding new user `grafana' (UID 110) with group `grafana' ...
Not creating home directory `/usr/share/grafana'.
### NOT starting on installation, please execute the following statements to
configure grafana to start automatically using systemd
sudo /bin/systemctl daemon-reload
sudo /bin/systemctl enable grafana-server
### You can start grafana-server by executing
sudo /bin/systemctl start grafana-server
無事起動したっぽいように見えたけど、なんかおかしい。
tky@terry:~$ sudo systemctl status grafana-server
× grafana-server.service - Grafana instance
Loaded: loaded (/lib/systemd/system/grafana-server.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sun 2022-10-02 03:25:57 UTC; 4min 48s ago
Docs: http://docs.grafana.org
Process: 109549 ExecStart=/usr/sbin/grafana-server --config=${CONF_FILE} --pidfile=${PID_FILE_DIR}/grafana-server.pid --packaging=deb cfg:default.paths.logs=$>
Main PID: 109549 (code=exited, status=200/CHDIR)
CPU: 42ms
Oct 02 03:25:57 terry systemd[1]: grafana-server.service: Scheduled restart job, restart counter is at 5.
Oct 02 03:25:57 terry systemd[1]: Stopped Grafana instance.
Oct 02 03:25:57 terry systemd[1]: grafana-server.service: Start request repeated too quickly.
Oct 02 03:25:57 terry systemd[1]: grafana-server.service: Failed with result 'exit-code'.
Oct 02 03:25:57 terry systemd[1]: Failed to start Grafana instance.
Webを相当探したけど、結局よくわからず、一度grafanaアンインストールしてこっちの手順でaptでいれたら動いた。なんだったんだ。
$ sudo apt-get install -y gnupg2 curl
$ curl https://packages.grafana.com/gpg.key | sudo apt-key add -
$ sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"
$ sudo apt-get update
$ sudo apt-get -y install grafana
$ sudo systemctl start grafana-server
画面をぐりぐり動かしてみているけど、サーバにかかる負荷小さいな。
適当にMySQLのデータをPanelにしてみるけどこれも問題なし。
いじってて見つけたのだけど、Organizationっていう機能がある。これ、pythonとかのスクリプトとかで自動生成してテンプレのDashboardをImportしてWebアプリ側に合わせて動かすとかできるのかな・・・。
この辺はちょっと勉強していかないとな。しかし日本語化は全くできないようだなあ。これ後々障壁になるかな。
自前のWebアプリ(Python Django)を作っているのだけど、ポンと入ったトップページに昨今のBIツールっぽいダッシュボードがあるといいなと思い、どうにも気になって調べ始めている。要件は
1も2もできることは確認しているのだけど、3がどうにもわからん。
英語が多いので、そもそものところから調べながらどこまで使えるか確認してみる。
Viewで
result = SomeModel.objects.filter(p=p).values('key__id').annotate(sum=models.Sum('value'))
って感じでannotateでとあるキーに合致するレコードのサマリをとろうとしたのだが、resultはQuerySetだから
result[0]['sum']
なんてアクセスするとエラー(list index out of range)がでて、あー、だめなのかって思った。そこで
result.first()['sum']
ってやると、あー動いた動いたって安心してたんだけども、どうも合計が10.0あるレコードも集計されてなくて1.0とかになっておかしい。first()のせいで、1レコード分だけをSumしている挙動と思われる・・・。[0]自体はよくて、集計対象の行がないときに[0]はエラーになっているというだけなのだった。つまりこれでよかった。
if(result.count == 0):
val = 0
else:
val = resuilt[0].get('sum')
なんかコードがすっきりしないけど、これくらいなら1行で書く方法が何かありそう。
PHPだと $a = ( $i == “OK” ? True : False ) みたいなのができたけどpythonもあるのかな。
追記:調べてたら見つけた。
val = 0 if result.count == 0 else result[0].get('sum')
とか、勤務先の社食でごはん食べながらかいていたら、前に座った人がふところからラー油取り出してて、なんだこの人、ラー油常に持ってるのか。
Djangoで何かを一覧で見るときにPaginateしたいのだが、例によって時間かけずに簡単にやりたい。
https://medium.com/@kjmczk/django-pagination-7c497995561e
こちらなど参考になったが、CSSがどこでどう設定したらきれいになるのかよくわからないのと、あとget_query_setとか、get_contextとか、この辺がやっぱりわかりにくい。一応なんかそれっぽく動いたけども、コードのメンテがめんどくさそうだ。なんかやろうとするたびに調べないといけなさそう。
結局Paginator的なSnippetはtemplatesに以下くらいを作って
{% if is_paginated %}
<p class="paginator">
{% for num in paginator.page_range %}
{% if page_obj.number == num %}
<!-- <li class="page-item active"> -->
<span class="this-page">{{ num }}</span>
<!-- </li> -->
{% else %}
<!-- <li class="page-item"> -->
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
<!-- </li> -->
{% endif %}
{% endfor %}
{% endif %}
Djangoの公式マニュアル見たら、GenericなListView使わずにこうやって書く方法が見つかった。
from django.core.paginator import Paginator
from django.shortcuts import render
from myapp.models import Contact
def listing(request):
contact_list = Contact.objects.all()
paginator = Paginator(contact_list, 25) # Show 25 contacts per page.
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'list.html', {'page_obj': page_obj})
あとでこれで書き直そう。
DjangoのForm関連の機能は手間を色々減らしてくれる気がするので、ぜひ使い方をマスターして活用したいな、と思っていたけど、かゆいところに手が届かいので、一部あきらめる。
[app/form.py]
from django import forms
from .models import Project
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ["field1", "field2", "field3"]
これだけでFormオブジェクトそのものはできちゃうので、Viewに1行くらいコンテキストに渡す処理書いてあげるだけで、Template側では
<form method="POST"> {% csrf_token %}
<fieldset class="module aligned">
{% for field in form %}
<div class="form-row"><div>
<label>{{ field.label_tag }}</label>
<div class="related-widget-wrapper">
{{ field }}
{{ field.errors }}
</div>
</div></div>
{% endfor %}
<input name="submit" type="submit" value="Regist" />
</fieldset>
</form>
これ書いてあげるだけでフォーム作ってくれちゃうし、こりゃ今後フィールド増えたときも便利だなあと確かに助かったんだけども、View側でPOSTを受け取ったときが困り物で
if(request.method == 'POST'):
form = ProjectForm(request.POST)
if not form.is_valid():
これ、Formのフィールドからはあえて削ったフィールドについては、手で横からセットしてあげることが多分できないんじゃないだろうか。無理やりrequest.POSTの中身をいじってから処理するのもなんか違う。上記の例だとformのオブジェクトに対してなんかメソッドやらでsetすることはできないのかと調べたものの出てこないし、Validationなんかも怪しいところだ・・・。
色々考えたすえ、ModelFormは画面の生成と一定のValidationでは頼ってみることにするけど、データ編集してDBにレコード保存する処理はModelで直で書いてあげることにする。これはもうその方がわかりやすい。
したら、Viewはこんなことになった。ピエン。
if(request.method == 'POST'):
form = ProjectForm(request.POST)
if not form.is_valid():
ctx['form'] = form
else:
p = request.POST
pj = Project(
field1=p['field1'],
field2=p['field2'],
field3=p['field3'],
field4=xxxxxxx, # Formからではなく自分で別の方法で取得させる
field5=xxxxxxx, # Formからではなく自分で別の方法で取得させる
)
pj.save()
messages.success(request, 'Success')
return redirect('xxxx:xxxxx')
いいのかなこれ。ちゃんと動いて、あとからメンテできればいいっていうポリシーでやってるけど、不安だ。
Atomをデスクトップメニューから起動しようとしても、しばらくしたらダウンしてしまう症状。
試しにシェルから起動してみたらこんなログが出ておる。Linux版のAtomはなんかトラブルが多いな。
user@xxx:~ $ atom
user@xxx:~ $ /usr/bin/atom: line 195: 3122 Illegal instruction (core dumped) nohup "$ATOM_PATH" --executed-from="$(pwd)" --pid=$$ "$@" > "$ATOM_HOME/nohup.out" 2>&1
(node:3190) Electron: Loading non-context-aware native module in renderer: '/usr/share/atom/resources/app.asar.unpacked/node_modules/superstring/build/Release/superstring.node'. This is deprecated, see https://github.com/electron/electron/issues/18397.
(node:3190) Electron: Loading non-context-aware native module in renderer: '/usr/share/atom/resources/app.asar.unpacked/node_modules/pathwatcher/build/Release/pathwatcher.node'. This is deprecated, see https://github.com/electron/electron/issues/18397.
[3122:0919/131037.889620:FATAL:gpu_data_manager_impl_private.cc(439)] GPU process isn't usable. Goodbye.
GPU processが使えないってなんだよ・・・とググって見たけど
https://forum.manjaro.org/t/error-gpu-process-isnt-usable-goodbye/104611
こちらを発見して、以下の太字のところだけ追加したらスッキリ解決。意味は不明だけど別にいいか。。。
$ sudo vim /usr/share/applications/atom.desktop
[Desktop Entry]
Name=Atom
Comment=A hackable text editor for the 21st Century.
GenericName=Text Editor
Exec=env ATOM_DISABLE_SHELLING_OUT_FOR_ENVIRONMENT=false /usr/bin/atom %F --no-sandbox
Icon=atom
Type=Application
StartupNotify=true
Categories=GTK;Utility;TextEditor;Development;
MimeType=application/javascript;application/json;application/x-httpd-eruby;application/x-httpd-php;application/x-httpd-php3;application/x-httpd-php4;application/x-httpd-php5;application/x-ruby;application/x-bash;application/x-csh;application/x-sh;application/x-zsh;application/x-shellscript;application/x-sql;application/x-tcl;application/xhtml+xml;application/xml;application/xml-dtd;application/xslt+xml;text/coffeescript;text/css;text/html;text/plain;text/xml;text/xml-dtd;text/x-bash;text/x-c++;text/x-c++hdr;text/x-c++src;text/x-c;text/x-chdr;text/x-csh;text/x-csrc;text/x-dsrc;text/x-diff;text/x-go;text/x-java;text/x-java-source;text/x-makefile;text/x-markdown;text/x-objc;text/x-perl;text/x-php;text/x-python;text/x-ruby;text/x-sh;text/x-zsh;text/yaml;inode/directory
StartupWMClass=atom
~