AB型技術系 主に備忘録

ほぼプログラム関連の備忘録

max-widthでスマホサイトの画像サイズを自動調整

PCサイトの画像をスマホで表示すると横幅が大きすぎてはみでてしまいました。

f:id:freelancer13:20170407025530j:plain

最初からスマホでも見れるように画像の大きさを調整しておけばよかったです・・・

既に多くの画像でページを作成しているのでリサイズするのは面倒です

そこでスマホサイト用のCSSに以下の記述を追加しました

#contents img {
	max-width: 100%;
	height: auto;
}

これで#contents内の画像の横幅をスマホの横幅におさまるようにサイズを調整してくれます
高さも自動で調整してくれます

f:id:freelancer13:20170407025537j:plain

いいかんじにおさまったのではないでしょうか


正規表現で特定の文字列を含まない行、含む行を抽出

先日とある会社のシステムのリリースがありました。

かなり大規模なシステムなので予想通りリリース後
いろいろと問題が発生し、ログ解析する日々です。

ログのフォーマット

2017/03/22 12:00:03 INFO START testAction1.do
2017/03/22 12:00:06 INFO END testAction1.do
2017/03/22 12:00:08 INFO START xxxAction2.do
2017/03/22 12:00:10 FATAL java.lang.NullPointerException
   ・
   ・
   ・
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
   ・
   ・
   ・
2017/03/22 12:03:08 INFO START xxxAction3.do
2017/03/22 12:00:10 WARN xxx.ValidateException
   ・
   ・
   ・
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

Javaで構築されたシステムで、予期しない例外が発生するとログに内容が出力されます。

ログから"Exception"を含む行を秀丸エディタgrepして目的の行を検索するのですが、使用しているフレームワークが出力する例外(ValidateException)が大量に出力されて数千件ヒットしてしまいます。

そこで正規表現を使って"Exception"を含む行かつ
"ValidateException"を含まない行を抽出できるようにしました

^(?!.*ValidateException).*(?=Exception).*$

^(?!.*ValidateException).*$で"ValidateException"を含まない行がマッチします。

そこに(?=Exception)を合わせることによって
"ValidateException"を含まない行、
かつ"Exception"を含む行がマッチします。

これで検索結果がかなり絞られましたが、他にもチェック不要な例外(TimeOutException)が
あることが判明

この例外も除外したいので"ValidateException"と"TimeOutException"を含まない行に条件を変更しました

^(?!.*(ValidateException|TimeOutException)).*(?=Exception).*$

除外したい文字列を()で囲んで|で区切るだけです。

これでログ解析の効率がかなりアップしましたよ。


HTTP_USER_AGENTを利用してcssを切り替える

PC用のcssスマホ用のcssを用意してデバイスによって読み込むcssを切り替えたいと思います。

最初に考えたのがlink要素の「media」属性を利用すること
メディアクエリというやつです

PC用

<link rel="stylesheet" type="text/css" media="screen and 
(min-width:901px)" href="css/style_pc.css"/>

画面サイズが901px以上の場合、style_pc.cssを読み込みます

スマホ

<link rel="stylesheet" type="text/css" media="screen and
 (max-width:900px)" href="css/style_smp.css"/>

画面サイズが900px以下の場合、style_smp.cssを読み込みます

しかし、この方法だと画面サイズが判断されるのでPCで画面サイズを小さくした場合style_smp.cssを読み込んでしまいます

最近はスマホでも画面サイズが大きいのでスマホがstyle_pc.cssを読み込む可能性もあります

そこでユーザーエージェントを利用してcssを切り替えることにしました

<?php
$ua=$_SERVER['HTTP_USER_AGENT'];
$isSmp = ((strpos($ua,'iPhone')!==false)||
  (strpos($ua,'iPad')!==false)||
  (strpos($ua,'Android')!==false));
?>

$_SERVER['HTTP_USER_AGENT']でユーザが利用しているOS情報等が取得できます

strposでユーザーエージェントにiPhoneiPadAndroidという文字列が存在するかチェックし
存在すればスマホと判断します

<?php if ($isSmp) {?>
<link rel="stylesheet" type="text/css" href="/css/style_smp.css" />
<?php } else {?>
<link rel="stylesheet" type="text/css" href="/css/style_pc.css" />
<?php }?>

$isSmpの値でスマホかどうか判別し読み込むcssを切り替えます

この状態でmax-device-withやmax-with等使ってスマホ用のレイアウトを
スマホタブレットに切り替えたりPC用のレイアウトを解像度が低いPCと高いPCに
切り替えたりするのもいいかなと思ってます


viewportを指定してスマホでも見やすくする

勉強も兼ねて構築中のサイトをスマホでみると非常にみにくい
何故ならPC用のサイトしか用意していないから

PC用のサイトが9割ほど完成したのでスマホ用のデザインもぼちぼち考えていきます

PC用のサイトをスマホでみるとみにくい原因はというと、
スマホがPC用のサイトを表示する時は横幅が980pxで表示しようとするかららしいです

自分のスマホの横幅をscreen.widthで取得すると360pxでした
そこに横幅980pxのレイアウトを合わせようとするので縮小されて表示されます

PCサイトをスマホで表示
f:id:freelancer13:20170312133926j:plain

対策は横幅980pxで表示しようとするのを360pxにすればよいです
そのためにはviewpointを指定します

<meta name="viewport" content="width=device-width;" />

viewport指定後のPCサイトをスマホで表示
f:id:freelancer13:20170312133925j:plain

device-widthでスマホの横幅に合うようになり縮小されずに表示されました
しかし横向きにすると横幅が広がるため拡大してします

スマホを横向きにして表示
f:id:freelancer13:20170312133924j:plain


viewportの記述を下記にすることで横向きにしても拡大されません

<meta name="viewport" content="width=device-width,
initial-scale=1.0,minimum-scale=1.0,
maximum-scale=1.0,user-scalable=no">

viewportを変更して表示
f:id:freelancer13:20170312133923j:plain

拡大されずに表示されました
ただし、この指定をするとピンチによる拡大縮小ができません

個人的には拡大縮小できなくてもいいと思ってるのでこの設定をベースにスマホ用のcssを作成してPCとスマホのデザインを切り分けていきたいと思ってます


grepやめてawkにする

仕事でやることがなくなってきました。

その結果、本来はJavaJavaScript使ってWebアプリ作ってますが、それ以外の仕事もふられるようになりました。

今回ふられたのはLinux上で動いてるログ監視シェルの修正。

正直得意ではないけど出来ませんと言うと切られるので勿論引き受けました。

フリーランスは辛いです。

やることはログの出力フォーマットが変わったのでそれに合わせて解析方法を修正すること

現在のログのフォーマット
ERROR 2016-12-10 03:21:03,523 ERR001 エラー発生

現在のシェル

let ERROR_COUNT= `grep ^$ERROR /var/log/error.log | wc -l`
  • grepでログファイルの各行の先頭がERRORではじまる行を出力
  • wcで行数を出力
  • 結果をERROR_COUNTに設定

この後に前回解析時のエラー件数をファイルから読み込んでERROR_COUNTの件数と比較、
増えてればエラーが発生したことをメール送信します

変更後のログのフォーマット
2016-12-10 03:21:03,523 ERROR ERR001 エラー発生

エラーの発生日付が先頭に出力されるように変更されました

変更後のシェル

let ERROR_COUNT= `awk '{if($4=="ERROR") print $1}' /var/log/error.log | wc -l`
  • awkでログファイルの各行を区切り文字(デフォルトはスペース)で区切る
  • 区切った文字の4つ目がERRORであれば区切った文字の1つ目を出力
  • wcで行数を出力
  • 結果をERROR_COUNTに設定

ERROR_COUNTに設定するコマンドを変更しただけで後は変更なし

awkは複雑な文字列操作ができますね。

簡単な解析ならgrepでできますが、複雑になるならawkの出番が増えそうです