UserAgent情報からSQLでOSとブラウザを簡易的に判別/集計する

PostgreSQLにて、DBに保存されたUserAgent情報からSQLでOSとブラウザを簡易的に判別/集計する。

  • ロボットの事は考慮していない。
  • ChromeのUserAgentには、「Safari」という文字列が含まれるので、Safariより先に判定する。
  • MSIE」は「IE 10」まで、「IE 11」は「MSIE」が削除されて「Trident」と「rv:11.0」と表示される。
  • 互換表示の場合、IE10:MSIE 7.0 と Trident/6.0 のように出てくるので、Tridentだけ判定して、「rv」があれば「rv」までを抽出。
  • Tridentとrevの間に、「Touch」「MALNJS」「MAFSJS」などが入っているものがあるが、そのまま抽出。
  • Mac OS Xのバージョンの表示は、FireFoxの場合「10.11」、その他の場合「10_11」と表記が異なる。
  • 期限切れの「Windows NT 5.1」=「Windows XP」が含まれているが、テストなので気にしない。

例えば、logテーブルのuser_agentというカラムにUserAgent情報が保存されている場合に、OSとブラウザの種類・バージョンをグループ化して件数を調べる。

db_name=> SELECT
  COUNT(*),
  CASE
    WHEN user_agent LIKE '%Macintosh%'  THEN SUBSTRING(user_agent from E'\(Mac OS[^)|;]*\)')
    WHEN user_agent LIKE '%iPad%'       THEN SUBSTRING(user_agent from E'\(iPad[^)]*\)')
    WHEN user_agent LIKE '%iPhone%'     THEN SUBSTRING(user_agent from E'\(iPhone[^)]*\)')
    WHEN user_agent LIKE '%Linux%'      THEN SUBSTRING(user_agent from E'\(X11[^)]*\)')
    WHEN user_agent LIKE '%Windows NT%' THEN SUBSTRING(user_agent from E'\(Windows NT [0-9.]+\)[)|;].*')
    ELSE user_agent
   END AS os,
  CASE
    WHEN user_agent LIKE '%Edge%'     THEN SUBSTRING(user_agent from E'\(Edge/[0-9.]+\)')
    WHEN user_agent LIKE '%Sleipnir%' THEN SUBSTRING(user_agent from E'\(Sleipnir/[0-9.]+\)')
    WHEN user_agent LIKE '%OPR%'      THEN SUBSTRING(user_agent from E'\(OPR/[0-9.]+\)')
    WHEN user_agent LIKE '%Vivaldi%'  THEN SUBSTRING(user_agent from E'\(Vivaldi/[0-9.]+\)')
    WHEN user_agent LIKE '%Firefox%'  THEN SUBSTRING(user_agent from E'\(Firefox/[0-9.]+\)')
    WHEN user_agent LIKE '%Chrome%'   THEN SUBSTRING(user_agent from E'\(Chrome/[0-9.]+\)')
    WHEN user_agent LIKE '%Trident%'  THEN SUBSTRING(user_agent from E'\(Trident/[0-9.]+;[^)]*\)')
    WHEN user_agent LIKE '%MSIE%'     THEN SUBSTRING(user_agent from E'\(MSIE [0-9.]+\)')
    WHEN user_agent LIKE '%Safari%'   THEN SUBSTRING(user_agent from E'\(Version/[0-9.]+ .*Safari/[0-9.]+\)')
    ELSE user_agent
   END AS browser
FROM
  log
GROUP BY
  os, browser
ORDER BY
  os, browser;


次のような結果になる。

 count |                 os                  |               browser
-------+-------------------------------------+-------------------------------------
     2 | Mac OS X 10.11                      | Firefox/46.0
     1 | Mac OS X 10_11_5                    | Chrome/50.0.2661.102
    10 | Mac OS X 10_11_5                    | Version/9.1.1 Safari/601.6.17
     9 | Windows NT 10.0                     | Chrome/50.0.2661.102
    19 | Windows NT 10.0                     | Edge/13.10586
     7 | Windows NT 10.0                     | Firefox/46.0
     1 | Windows NT 10.0                     | Sleipnir/6.1.11
     9 | Windows NT 10.0                     | Trident/7.0; rv:11.0
     1 | Windows NT 5.1                      | Chrome/49.0.2623.112
     1 | Windows NT 5.1                      | Firefox/46.0
     2 | Windows NT 6.0                      | Chrome/49.0.2623.112
     4 | Windows NT 6.1                      | Chrome/52.0.2743.10
    17 | Windows NT 6.1                      | Firefox/46.0
     1 | Windows NT 6.1                      | OPR/37.0.2178.43
     1 | Windows NT 6.1                      | Trident/7.0; MAFSJS; rv:11.0
    22 | Windows NT 6.1                      | Trident/7.0; rv:11.0
     1 | Windows NT 6.1                      | Vivaldi/1.1.453.59
     2 | Windows NT 6.3                      | Chrome/51.0.2704.63
     5 | Windows NT 6.3                      | Firefox/46.0
     1 | Windows NT 6.3                      | OPR/37.0.2178.43
     1 | Windows NT 6.3                      | Trident/7.0; MALNJS; rv:11.0
     3 | Windows NT 6.3                      | Trident/7.0; Touch; rv:11.0
     4 | Windows NT 6.3                      | Trident/7.0; rv:11.0
     1 | X11; Linux x86_64; rv:31.0          | Firefox/31.0
     1 | X11; Ubuntu; Linux x86_64; rv:46.0  | Firefox/46.0

CentOS 7のPHPでOCI関数を使うまで

【環境】
CentOS 7.2.1511

PHPのoci関数を利用するまでの手順。(PHP本体はインストール済みの状態)

最初に「Oracle Instant Client」を導入する。

Oracle社のWebサイトから、RPMファイルを入手する。アカウント登録が必要。

色々とパッケージがあるが、以下の2つで良い。
 ・Basic
 ・SDK

RPMコマンドでインストール。

# rpm -ivh oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm
# rpm -ivh oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm

必要なライブラリがインストールされる。

# rpm -ql oracle-instantclient12.1-basic
/usr/lib/oracle/12.1/client64/bin/adrci
/usr/lib/oracle/12.1/client64/bin/genezi
/usr/lib/oracle/12.1/client64/lib/libclntsh.so.12.1
/usr/lib/oracle/12.1/client64/lib/libclntshcore.so.12.1
/usr/lib/oracle/12.1/client64/lib/libipc1.so
/usr/lib/oracle/12.1/client64/lib/libmql1.so
/usr/lib/oracle/12.1/client64/lib/libnnz12.so
/usr/lib/oracle/12.1/client64/lib/libocci.so.12.1
/usr/lib/oracle/12.1/client64/lib/libociei.so
/usr/lib/oracle/12.1/client64/lib/libocijdbc12.so
/usr/lib/oracle/12.1/client64/lib/libons.so
/usr/lib/oracle/12.1/client64/lib/liboramysql12.so
/usr/lib/oracle/12.1/client64/lib/ojdbc6.jar
/usr/lib/oracle/12.1/client64/lib/ojdbc7.jar
/usr/lib/oracle/12.1/client64/lib/xstreams.jar

# rpm -ql oracle-instantclient12.1-devel
/usr/include/oracle/12.1/client64/ldap.h
/usr/include/oracle/12.1/client64/nzerror.h
/usr/include/oracle/12.1/client64/nzt.h
/usr/include/oracle/12.1/client64/occi.h
/usr/include/oracle/12.1/client64/occiAQ.h
/usr/include/oracle/12.1/client64/occiCommon.h
/usr/include/oracle/12.1/client64/occiControl.h
/usr/include/oracle/12.1/client64/occiData.h
/usr/include/oracle/12.1/client64/occiObjects.h
/usr/include/oracle/12.1/client64/oci.h
/usr/include/oracle/12.1/client64/oci1.h
/usr/include/oracle/12.1/client64/oci8dp.h
/usr/include/oracle/12.1/client64/ociap.h
/usr/include/oracle/12.1/client64/ociapr.h
/usr/include/oracle/12.1/client64/ocidef.h
/usr/include/oracle/12.1/client64/ocidem.h
/usr/include/oracle/12.1/client64/ocidfn.h
/usr/include/oracle/12.1/client64/ociextp.h
/usr/include/oracle/12.1/client64/ocikpr.h
/usr/include/oracle/12.1/client64/ocixmldb.h
/usr/include/oracle/12.1/client64/ocixstream.h
/usr/include/oracle/12.1/client64/odci.h
/usr/include/oracle/12.1/client64/oratypes.h
/usr/include/oracle/12.1/client64/ori.h
/usr/include/oracle/12.1/client64/orid.h
/usr/include/oracle/12.1/client64/orl.h
/usr/include/oracle/12.1/client64/oro.h
/usr/include/oracle/12.1/client64/ort.h
/usr/include/oracle/12.1/client64/xa.h
/usr/lib/oracle/12.1/client64/lib/libclntsh.so
/usr/lib/oracle/12.1/client64/lib/libclntshcore.so
/usr/lib/oracle/12.1/client64/lib/libocci.so
/usr/lib/oracle/12.1/client64/lib/ottclasses.zip
/usr/share/oracle/12.1/client64/admin/oraaccess.xsd
/usr/share/oracle/12.1/client64/demo/cdemo81.c
/usr/share/oracle/12.1/client64/demo/demo.mk
/usr/share/oracle/12.1/client64/demo/occidemo.sql
/usr/share/oracle/12.1/client64/demo/occidemod.sql
/usr/share/oracle/12.1/client64/demo/occidml.cpp
/usr/share/oracle/12.1/client64/demo/occiobj.cpp
/usr/share/oracle/12.1/client64/demo/occiobj.typ
/usr/share/oracle/12.1/client64/demo/oraaccess.xml
/usr/share/oracle/12.1/client64/demo/ott
/usr/share/oracle/12.1/client64/demo/setuporamysql.sh


次に、oci8モジュールを導入する。

PECLからoci8関数を導入。

# pecl install oci8

とするとエラーになる。

PHP 7未満の場合は、「oci8-2.0.11」を指定するようにとの事。
https://pecl.php.net/package/oci8

# pecl install oci8-2.0.11

/usr/lib64/php/modules/oci8.so が生成される。


モジュールを読み込むため、/etc/php.d/oci8.ini を作成する。

; Enable oci8 extension module
extension=oci8.so

httpdを再起動

# systemctl restart httpd

モジュールが読み込まれているか確認。

$ php -m | grep oci
oci8

phpinfo で確認する場合の例。

$ php -i | egrep -i 'oracle|oci'
/etc/php.d/oci8.ini,
oci8
OCI8 Support => enabled
OCI8 DTrace Support => disabled
OCI8 Version => 2.0.11
Oracle Run-time Client Library Version => 12.1.0.2.0
Oracle Compile-time Instant Client Version => 12.1
oci8.connection_class => no value => no value
oci8.default_prefetch => 100 => 100
oci8.events => Off => Off
oci8.max_persistent => -1 => -1
oci8.old_oci_close_semantics => Off => Off
oci8.persistent_timeout => -1 => -1
oci8.ping_interval => 60 => 60
oci8.privileged_connect => Off => Off
oci8.statement_cache_size => 20 => 20


「oci_connect」関数が存在するかチェック。

$ php --rf oci_connect
Function [ <internal:oci8> function oci_connect ] {

  - Parameters [5] {
    Parameter #0 [ <required> $username ]
    Parameter #1 [ <required> $password ]
    Parameter #2 [ <optional> $connection_string ]
    Parameter #3 [ <optional> $character_set ]
    Parameter #4 [ <optional> $session_mode ]
  }
}

存在しない場合。

$ php --rf oci_connect
Exception: Function oci_connect() does not exist

CentOS 7 へ Tigervnc Server を導入する

yum でインストール

# yum install tigervnc-server

VNCパスワードを設定(ユーザ毎)

$ vncpasswd

ディスプレイ番号「1」、解像度「1024x768」、色深度「24」でVNCプロセスを起動

$ vncserver :1 -geometry 1024x768 -depth 24

※上記はVNCサーバの起動ではなく、プロセスの起動。サービスとして扱うには、ユニットファイルを用意する必要がある。

停止する場合は、-killオプションを付けてディスプレイ番号を指定。

$ vncserver -kill :1

※上記の場合、VNCの待受けポートは5901番ポートなので、FWを適切に設定する。

Xfceを使うには、~/.vnc/xstartup の最後に以下を記載する。
「exec /etc/X11/xinit/xinitrc」の行はコメントアウト

#exec /etc/X11/xinit/xinitrc
exec xfce4-session &


Xface の導入は下記に記載しました。
shobon.hatenablog.com


CentOS 7を最小インストールした場合、日本語が文字化けするので、以下のようにする。

日本語関連のパッケージをインストール

# yum install ibus-kkc vlgothic-*

再ログインすれば良い。ダメならVNCプロセスを再起動してみる。

CentOS 7 でXfceを使う

CentOS 7にて、普段は「multi-user.target」な環境だけれど、VNC経由で一時的にGUI環境が欲しいだけの場合、インストーラで「Server With GUI」を指定すると、余計なものがたくさん入って困った。

CentOS 7を最小インストール → 後からXfceを導入、の方が余計なものが少なく、希望の要件を満たせたのでメモ。

X Windowのインストール

# yum groups install "X Window System"

epel-releaseのインストール(EPELからxfceをダウンロードするため)

# yum install epel-release

EPELリポジトリのデフォルトを無効に設定(/etc/yum.repos.d/epel.repo)

enabled=1
 ↓
enabled=0

xfceのインストール

# yum groups install --enablerepo=epel xfce

導入前後の容量は、GNOMEほど多くなく、500MBくらいの模様。

PHP5.4以降で削除される関数の一覧

一覧が欲しかったので、まとめてみた。

関数名 削除バージョン 非推奨バージョン PHPマニュアルURL  
define_syslog_variables 5.4 5.3 http://php.net/manual/ja/function.define-syslog-variables.php
import_request_variables 5.4 5.3 http://php.net/manual/ja/function.import-request-variables.php
mysqli_bind_param 5.4 5.3 http://php.net/manual/ja/function.mysqli-bind-param.php
mysqli_bind_result 5.4 5.3 http://php.net/manual/ja/function.mysqli-bind-result.php
mysqli_client_encoding 5.4 5.3 http://php.net/manual/ja/function.mysqli-client-encoding.php
mysqli_fetch 5.4 5.3 http://php.net/manual/ja/function.mysqli-fetch.php
mysqli_get_metadata 5.4 5.3 http://php.net/manual/ja/function.mysqli-get-metadata.php
mysqli_param_count 5.4 5.3 http://php.net/manual/ja/function.mysqli-param-count.php
mysqli_send_long_data 5.4 5.3 http://php.net/manual/ja/function.mysqli-send-long-data.php
session_is_registered 5.4 5.3 http://php.net/manual/ja/function.session-is-registered.php
session_register 5.4 5.3 http://php.net/manual/ja/function.session-register.php
session_unregister 5.4 5.3 http://php.net/manual/ja/function.session-unregister.php
php_logo_guid 5.5 http://php.net/manual/en/function.php-logo-guid.php
zend_logo_guid 5.5 http://php.net/manual/ja/function.zend-logo-guid.php
call_user_method 7.0 4.1 http://php.net/manual/ja/function.call-user-method.php
call_user_method_array 7.0 4.1 http://php.net/manual/ja/function.call-user-method-array.php
datefmt_set_timezone_id 7.0 5.5 http://php.net/manual/ja/intldateformatter.settimezoneid.php
dl 7.0 5.3 http://php.net/manual/ja/function.dl.php
ereg 7.0 5.3 http://php.net/manual/ja/function.ereg.php
ereg_replace 7.0 5.3 http://php.net/manual/ja/function.ereg-replace.php
eregi 7.0 5.3 http://php.net/manual/ja/function.eregi.php
eregi_replace 7.0 5.3 http://php.net/manual/ja/function.eregi-replace.php
magic_quotes_runtime 7.0 5.3 http://php.net/manual/ja/function.magic-quotes-runtime.php
mcrypt_cbc 7.0 5.5 http://php.net/manual/ja/function.mcrypt-cbc.php
mcrypt_cfb 7.0 5.5 http://php.net/manual/ja/function.mcrypt-cfb.php
mcrypt_ecb 7.0 5.5 http://php.net/manual/ja/function.mcrypt-ecb.php
mcrypt_generic_end 7.0 5.3 http://php.net/manual/ja/function.mcrypt-generic-end.php
mcrypt_ofb 7.0 5.5 http://php.net/manual/ja/function.mcrypt-ofb.php
mysql_db_query 7.0 5.3 http://php.net/manual/ja/function.mysql-db-query.php
mysql_escape_string 7.0 4.3 http://php.net/manual/ja/function.mysql-escape-string.php
mysql_list_dbs 7.0 5.4 http://php.net/manual/ja/function.mysql-list-dbs.php
set_magic_quotes_runtime 7.0 5.3 http://php.net/manual/ja/function.set-magic-quotes-runtime.php
set_socket_blocking 7.0 5.3 http://php.net/manual/ja/function.set-socket-blocking.php
split 7.0 5.3 http://php.net/manual/ja/function.split.php
spliti 7.0 5.3 http://php.net/manual/ja/function.spliti.php
sql_regcase 7.0 5.3 http://php.net/manual/ja/function.sql-regcase.php


【追記ここから(2016/4/8)】
CentOS 5/6/7 のBase.repo にあるPHPのバージョンも書いておく。

CentOS Base.repo にあるPHPのバージョン
5 5.1.6/5.3.3(php53)
6 5.3.3
7 5.4.16

【追記ここまで】

Firefoxで入力カーソルが表示されるキャレットブラウズモード

知人から、「ネット見てたら、いつのまにか入力カーソルみたいなのが出て消えないんだけど?」って聞かれた時のこと。

画面キャプチャを送って貰ったら、Firefoxのキャレットブラウズモードの事でした。

例えば、以下のような感じ。赤い矢印で指されてる部分。
f:id:savakan:20160312144613p:plain

入力フォームでもない場所で、図のような入力カーソルが表示される。

Firefox 45の場合、[オプション] - [詳細] - [一般] - [アクセシビリティ] にて、「ページ中の移動にカーソルを使用する(キャレットブラウズモード)」という項目で設定できるほか、「F7」キーを押しても切り替えが可能。

検索文字をF7でカタカナに変換してEnterを押したつもりが、検索フォームにカーソルが入っていない状態でF7を押してしまい、うっかりキャレットブラウズモードになってしまう事がある?

とは言っても、モードを切り替える注意書きが出るので、よく読まずに「はい」を選択していると思われる。(知人は多分これに該当)

f:id:savakan:20160312144607p:plain


ところで、キャレットブラウズモードになっていると、キーボードの「Home」と「End」の挙動が変わる。

通常のモード:Home→ページ最上部へ移動、End→ページ最下部へ移動

キャレットブラウズモード:Home→キャレットが行頭へ移動、End→キャレットが行末へ移動

「入力カーソルが表示されるようになった」とか「Home/Endで上下へ移動/スクロールできなくなった」事からモードが切り替わった事に気が付くので、気に入らなければ設定を戻すと良い。

vSphere 6.0u1 で仮想マシン作成時のゲストOS選択に Windows Server 2012 R2 が無い

VMware製品で仮想マシンを作成する際に、ゲストOSの種類を選択する項目がある。

vSphere6のドキュメントによると、ここの選択肢は次のような影響を及ぼす。

テンプレートまたはクローンを使用しない仮想マシンの作成
vSphere 6.0 Documentation Center

ゲスト OS の選択
vSphere 6.0 Documentation Center

選択したゲスト OS によって、サポートされるデバイスおよび仮想マシンで使用可能な仮想 CPU の数が変化します。
ウィザードではこの情報を使用して、必要なメモリ サイズなど、適切なデフォルト値を選択します。


この選択肢で、ゲストOSの一覧に「Windows Server 2012 R2」が無い。

VMware vSphere/ESXi 6.0u1 の場合】
f:id:savakan:20160220143650p:plain

VMware vSphere/VCSA 6.0u1 の場合】
f:id:savakan:20160220143655p:plain

VMware WorkStation Player12.1 の場合】
f:id:savakan:20160220143751p:plain


これについては、以下のKBに記載がある。

Microsoft Windows Server 2012 R2 のゲスト OS オプションを使用できない (2093022)
https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2093022

Microsoft Windows Server 2012 R2 guest operating system option is not available (2069889)
https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2069889


結論としては、ゲストOSに「Windows Server 2012 R2」を利用する場合でも、仮想マシン作成時のゲストOS選択では、「Windows Server 2012」を選べば良い。