Mac上遇到的warning: setlocale: LC_CTYPE: cannot change locale (UTF-8)

這個問題之前遇到過幾次,每次都是透過iTerm2連接到remote linux server時跳出警告… 雖然問題不大,但昨天連到自家的機器又遇到一樣的問題時,還是決定來找一下解決方式!

這個警告主要影響的是使用者在iTerm2上的畫面顯示,只要用到UTF-8的地方會一直出現警告 !

解決方式

網路上找了一下相關的解決方式以後,大概可以分為兩種方式處理:

Server 端的解決方式

將下列的設定加入到 /etc/environment 裡面

LANG=en_US.utf-8
LC_ALL=en_US.utf-8

Client 端的解決方式(Mac)

將下列兩行環境變數加入到使用者的 ~/.bashrc~/.zshrc(基本上看client端這邊的shell環境)

export LC_ALL=en_US.UTF-8
export LANG=US.UTF-8

我目前採用Client端的解決方式,再重新做 source ~/.zshrc以後,目前就沒在遇到問題了!

Reference:

如何寫好Logs

寫好Log對我而言一直是一項重要的技能, 因為它可以讓問題發生時, 讓開發者用最短的時間找到並解決問題… 剛好在Hacker News上看到這篇 Logging in Python like a PRO , 順便紀錄一下這位作者的一些觀點…

好的Log所需具備的特性

* Descriptive
* Contextual
* Reactive

They’re descriptive in the sense that they give you a piece of information, they’re contextual because they give you an overview of the state of things at the moment, and finally, they’re reactive because they allow you to take action only after something happened (even though your logs are sent/consumed real-time, there’s not really something you can do to change what just happened).

https://guicommits.com/how-to-log-in-python-like-a-pro/

簡單來說如果一段log可以具備上述三個特性, 作者就認為可以讓log的讀者能夠更輕鬆的定位問題的發生點, 以及相對應的事件背景 !

Log 的時機點

As a rule of thumb consider logging:

* At the start of relevant operations or flows (e.g. Connection to third-party, etc);

* At any relevant progress (e.g. Authentication successful, got a valid response code, etc);

* At the conclusion of an operation (e.g. EITHER succeeded or failed);

https://guicommits.com/how-to-log-in-python-like-a-pro/

至於說何時要寫Log呢? 作者這邊指出事件的起始點, 相關的處理進度發生時, 以及事件處理完成時都是適合Log的時間點 !!!

Python 下的Logging的一些範例設定

Python上的一些Log設定我就不太熟了, 先紀錄一下之後可以看看….

總結

這篇文章算是簡單的提要了寫Log時的一些大方向, 這樣之後要寫也蠻適合當參考…

Reference:

透過Dehydrated來設定Let’s encrypt

之前是使用Certbot來更新我這個網誌的Let’s encrypt certificate,運作上也還算正常,但自動更新cert這邊常常更新不了(這部分感覺應該是我設定上的問題)…

後來在公司上, DK有提到了dehydrated這個輕量化的Let’s enrypt 設定工具,實際上去快速看了一下它的repoistory以後,真的覺得對於一般的Linux 環境使用上蠻友善的(因為它所需要的工具通常都是Linux 系統預設的工具)。

快速掃完以後,直接進入正題關於設定上的相關指令… (這邊直接參考 DK 的 wiki上的設定)

安裝Dehydrated

# using a temporary directory to download the dehydrated
cd ~/tmp
wget "https://raw.githubusercontent.com/dehydrated-io/dehydrated/master/dehydrated"
chmod +x dehydrated
sudo mv dehydrated /usr/local/bin/

Dehydrated環境設定

# create directories that dehydrated will need
sudo mkdir -p /etc/dehydrated /var/www/dehydrated

#change to the dehydrated dir
cd /etc/dehydrated

# setup the config
echo 'OCSP_MUST_STAPLE=yes' | sudo tee -a config
echo 'KEYSIZE=2048' | sudo tee -a config
echo 'WELLKNOWN=/var/www/dehydrated' | sudo tee -a config

# setup the domain file
echo 'blog.gechen.org' | sudo tee -a domains.txt
 

設定Nginx

這邊的範例主要是透過Nginx來當做之後dehydrated 執行時,用來回應Let’s encrypt 的challenge…

下面就直接貼Nginx 的對應domain的範例設定檔

server {
     listen 80;
     server_name blog.gechen.org;
     rewrite ^(.*) https://$host$1 permanent;
 }

server {
     listen 443 ssl;
     server_name blog.gechen.org;
     
     index index.php;
     ssl_certificate /etc/dehydrated/certs/blog.gechen.org/fullchain.pem;
     ssl_certificate_key /etc/dehydrated/certs/blog.gechen.org/privkey.pem;


     # ... skip some configs

   
     # this part is for dehydrated
     location /.well-known/acme-challenge/ {
        alias /var/www/dehydrated;
     }
 }

執行Dehydrated 來更新Let’s encrypt certs

如果是第一次使用 dehydrated 則要額外執行下面指令

sudo dehydrated --register --accept-terms

透過下面的指令來做Let’s encrypt certificate的申請/更新

# the following command will apply/renew certificates for the domains in file: /etc/dehydrated/domains.txt
sudo dehydrated -c

# or we can also directly use command below to apply for specific domain certificate
sudo dehydrated -c -d blog.gechen.org

設定自動更新certificate的cron jobs

這邊直接引用DK 大大的wiki範例來設定 weekly 的憑證更新…

echo -e '#!/bin/bash\nexport PATH=/usr/sbin:/usr/bin:/bin:"${PATH}"\nsleep $(expr $(printf "%d" "0x$(hostname | md5sum | cut -c 1-8)") % 86400); dehydrated -c && ( service nginx reload )' | sudo tee /etc/cron.weekly/dehydrated; sudo chmod 755 /etc/cron.weekly/dehydrated 

References:

透過jq 將json檔案格式輸出成 env格式

剛好工作上有這個需求, 就順便找了一下看 jq 指令是否可以簡單的做到這件事…

測試了下面的指令以後, 看起來真的是頗好用, 一行指令就可以把 json 轉成 env 了!

cat example.json| jq -r 'to_entries[] | [.key,.value] | join("=")' > example.env

Reference:

Database diff

從DK的blog上看到的分享工具 data-diff 後, 快速看了一下它的說明文件以後, 感覺這東西有需求的話應該會蠻不錯用的!

看起來可以比對多個data source的資料表, 而且預計支援的資料庫或相關服務也蠻多是市面上常見的… 蠻適合以後有需要時再來試看看.

Reference:

透過SQLite3 來用一指令實現SQL讀取CSV檔

看到DK的文章上提到這個功能覺得也太有趣了, 沒想到會有這麼簡單方式來從CSV檔中讀取想要的內容…

使用方式

將sqlite3 透過memory的方式讀取了以後, 就可以透過SQL來找到其中想要的內容了…

sqlite3 :memory: -cmd '.mode csv' -cmd '.import mds_content_status.csv temp' -cmd '.mode column' 'SELECT * FROM temp'

為了讓使用方式更方便, 還可以在.bashrc.zshrc中把上面的cli 指令包裝成 shell function 如下:

function query_csv() {
    local CSV_FILE=$1
    local TABLE=$2
    local QUERY=$3

    sqlite3 :memory: -cmd '.headers on' -cmd '.mode csv' -cmd ".import ${CSV_FILE} ${TABLE}" -cmd '.mode column' "${QUERY}"
}

然後我們就可以用下面的方式去query了…

query_csv users.csv user_table 'SELECT id, name FROM user_table where id=17807'

reference

Search Engine list

剛好在DK大大那邊看到的一篇搜尋引擎的整理文章, 我猜來源應該是Hacker News上有人發布的XDDD

文章的內容中提供了一大串的搜尋引擎相關的服務…. (沒想到有這麼多搜尋引擎阿阿阿!!!)
先紀錄一下, 找一天再來細看裡面收錄的搜尋引擎XDDD

reference:

Linux中網路界面速度的調整方式

最近剛好工作上有需要, 需要針對一些網路情況不佳的裝置去做一些實驗; 但問題來了, 要在實務上去真的找到這種裝置其實蠻難的, 這時候Linux 提供了一些很好模擬的方式來對特定的網路界面模擬上述情境…

限制網路界面的速率

再做了一些快速的瀏覽以後, 看起來在Linux中主要是透過 tc 這個指令來做 traffic control, 不過社群中有人提供了一個更簡便的方式 wondershaper, 如果OS是ubuntu 的話可以用 sudo apt-get install wondershaper 就可以安裝了.

一些常見的指令範例有:

設定eth1 的download=256kbps, upload=128kbps

sudo wondershaper eth1 256 128

清除 eth1的流量設定

sudo wondershaper clear eth1

設定網路界面的packet lost 機率

這個情境下, 我們可以模擬網路掉包在不同嚴重程度的情況下的情境; 主要是透過 iptables 來達成, 可以參考以下範例:

設定來源ip為 123.123.123.123 且封包到這台電腦的 local port為 3000時, 其packet drop的機率為 5%

sudo iptables -I INPUT -s 123.123.123.123 -p tcp --dport 3000 -m statistic --mode random --probability 0.05 -j ACCEPT

reference:

調低EBS 的磁碟大小

前言

最近收到AWS的個人帳單以後, 突然發現我帳單上的金額與我的想像有些落差, 也因為這樣子, 開始來對一下是哪些項目在吃錢…

大概對了一下, 發現主要的花費在EC2 instance 與 EBS 兩個項目上面, EC2 instance 這邊的花費就是題外話了, 但EBS這邊就慢讓我意外的… 細看了以後才發現當初不知道為什麼把使用的EBS 成 使用30GB, 但我實際上的使用也才6GB左右…
(雖然這也不是什麼大錢, 但每個月給它這樣扣也是覺得還不如把錢省下來去訂閱其他有用服務….)

第一次實驗

原本想說把root volume EBS 調低應該不是件難事, 結果沒想到AWS預設上是不支援這件是的, 它可以往上調高, 但不支援調低…

在網路上找了不少相關的教學文, 主要的作法都是, 大概都是…

  • 先建立一個較小的EBS volume
  • 再把這個新的 EBS volume 掛到我們的EC2上面以後, 做好格式化以及 rsync 的資料拷貝
  • 最後設定好 /boot 以後, 就可以把新的EBS volume來取代原有的 EBS root volume.
    (題外話, 要把EBS volume 設定為 EC2 上面的 /dev/sda1 才會成為那台EC2上的root volume)

第一次實驗結果

經由上述步驟的教學文實際嘗試以後, 都會卡再做出來的EBS volume是無法當成是原本這一台EC2的root volume, 它會直接讓那台EC2開不起來. (機器顯示 running, 但是ssh 連不到…)

上述的測試其實我參考了不少文章, 但最後卡的點都是一樣的, 做出來的 EBS volume是不能用的… (我這邊使用的EC2 t4g family, 不太確定跟ARM 版本的 grub-install 有關??? 也許今天使用的是x86的機器就可以? 之後有機會再來試試)

另一種Workaround的方式

因為上面測試也花了不少時間, 所以最後就自己做了一些流程上的調整如下:

  • 建立一台新的EC2, 並設定root volume為我想要的大小 (6GB), 並且OS的版本也是用與就機器一樣的 ubuntu 20.04
  • 接著, 將舊機器的EBS 掛到新的EC2機器上.
  • 透過 rsync 將舊的EC2 資料都複製到新的EC2上. (基本上除了 /boot, /tmp, /mnt, /dev以外, 都要sync 到新的EC2的對應資料夾)
  • 如果先前有設定route53, elastic IP 等等相關的設定, 最後都指定到這台新的EC2機器上.

最後靠這個方式成功把 EBS size降下來了, 不過靠這個方式比較像是duplicate出一台新的EC2, 而不是clone出一模一樣的機器…

Reference: