Viyaの運用を行うのであれば常備しておきたいツールです。テクニカルサポート問合せのときに使います。実行方法はREADMEのCommand-Line Mode Exampleを見てください。デプロイしたときの site.yaml のあるディレクトリを引数で指定します。
リンクが間違っていたので修正
SASプログラムとログを解析するユーティリティを開発するための備忘録です。This is a memo to develop utility that analyzes the SAS log.
2024年12月6日金曜日
get-k8s-info.sh Viyaの情報をまとめて集めるツール
2024年8月11日日曜日
SAS Viya Monitoring for Kubernetes からログを抽出するカスタムステップ
SAS Viyaでエラーを調査するときにOpenSearchでログを抽出するが、それを簡単に実行するカスタムステップがSAS Communities Libraryに紹介されている。ログの抽出が面倒な理由は複数ある。
- OpenSearchで抽出できるのは10,000件というAPIの上限がある。
- その制限の範囲内で抽出しようとすると手間がかかる。
- フィールドを毎回選ぶのが面倒だ。
2024年1月17日水曜日
PROC HTTPでトークンを取得するサンプル
PROC HTTPでユーザ名とパスワードを指定してアクセストークンを取得するサンプルです。通常はOAUTH_BEARER=SAS_SERVICES を使うことが多いですが、稀にトークン取得したいというニーズがあります。このコードで?な箇所は認証のヘッダーにsas.cli:をエンコードした値を使っているところです。コロンの前がクライアントのツール、コロンの後にパスワードを指定するのが普通ですが、パスワードは空の状態でエンコードしています。このパラメータはSAS Viya CLIからauth loginするときに--verboseで出力されるデバッグの情報を見てそれに倣っています。クライアントのパスワードが空なのは理解できませんが、ログを見るとそうなっています。時間あるときにPostmanでも同じようにパラメータを指定して動くか確かめます。
/* PROC Sample of using HTTP to obtain an access token. */
%let client=sas.cli;
%let cpassword=;
%let username=alex;
%let password=hogehoge;
%let host=%sysget(SAS_SERVICES_URL);
filename resp "/tmp/foo.txt";
data _null_;
attrib buf length=$64;
buf=put("&client.:&cpassword.", $base64x64.);
put buf=;
call symputx('code', compress(buf), 'G');
run;
proc http method="POST" url="&host./SASLogon/oauth/token"
in="grant_type=password%str(&)username=&username.%str(&)password=&password." out=resp timeout=15;
headers "authorization"="Basic &code"
"Content-Type"="application/x-www-form-urlencoded";
run;
data _null_;
infile resp truncover;
input;
put _INFILE_;
run;
2023年11月21日火曜日
SAS StudioからOpenSearchのログを検索するサンプル
Viyaのログの調査の効率を上げるためにSAS Studioからクエリを投入できないか思案しています。できたのが以下のコードです。
/* Sample code to search OpenSearch by PROC HTTP. */
filename myresult temp;
data _null_;
attrib code length=$64;
/* Change the following user name (admin) and password (hogehoge) to match your environment. */
code=put("admin:hogehoge", $base64x64.);
put code=;
call symputx('code', compress(code), 'G');
run;
proc http url="https://v4m-search.logging.svc.cluster.local:9200/_search"
in='{ "query": { "simple_query_string": { "query": "setinit", "fields": [ "message" ], "default_operator": "and" }}}'
out=myresult
timeout=30
/* clear_cache*/;
sslparms "SSLREQCERT"="allow" SSLCERTLOC="/opt/sas/viya/home/SASSecurityCertificateFramework/tls/certs/ca-bundle.pem";
headers "content-type"="application/json" "authorization"="Basic &code.";
debug level=0;
run;
data _null_;
infile myresult;
input;
put _INFILE_;
run;
このコードが意味するところは、messageフィールドからsetinitを検索しています。URLのホスト名、ポート番号とPEMのファイルはSAS Compute ServerのPodに接続して探したり、kubectl describe endpointsやservicesで探しました。それらのホスト名とかポート番号は公式なドキュメントには書かれていないので実機検証で調べてたものです。なので内部の実装は知らぬ間に変わる可能性があることに留意してください。2023年10月4日水曜日
OpenSearch を curl から検索する例
SAS Viya Monitoring for Kubernetes でログを検索したい場合に以下のようにクエリを投入できる。結果はJSONなので、これを加工して欲しい情報を見やすく成型する。この curl のコマンドは OpenSearch の DEV Toolからコマンドを生成して、必要最小限のオプションまで削りました。
curl 'https://viya4.example.com/dashboards/api/console/proxy?path=_search&method=GET' \
-H 'osd-xsrf: opensearchDashboards' \
--data-raw '{ "query": { "simple_query_string": { "query": "setinit", "fields": [ "message" ], "default_operator": "and" }}}' \
--insecure -u 'admin:password'
このコードが意味するところは、messageフィールドからsetinitを検索しています。-uでユーザ名とパスワードを指定しています。OpenSearch自体にクエリを投げる例はすぐに見つかりますが、クラスタ内部のサービスを指定する方法が判らず数時間調べました。
2023年6月26日月曜日
SAS Viya CLIのログインとトークンを環境変数に設定
シェルから . で読み込んでSAS Viya CLIと環境変数にトークンを設定する例です。curlと組み合わせて使うので、このスクリプトをよく使う。
sas-viya -k auth login -u sasadm -p hogehoge export ACCESS_TOKEN=$(cat ~/.sas/credentials.json | jq -r '.Default."access-token"') export URL=$(jq -r ' .Default."sas-endpoint"' ~/.sas/config.json) export LANG=en.UTF-8
2023年4月25日火曜日
2023年4月11日火曜日
JSONのファイルから32KBを超えるSASプログラムを抽出する。
LIBNAMEのJSONエンジンの欠点は、32KBを超える長さのデータを抽出できない点です。できないものは仕方ないので、32KBを超えてもSASプログラムを抽出するコードを書きました。
字句解析の状態遷移を考えて "code": の値を抽出してバックスラッシュのエンコードを解いてファイルの保存します。入力のJSONファイルは整形されていないコンパクトや書式の前提です。昔、Lex, Yaccを使っていた記憶を掘り起こした。
/* Code extraction from JSON file of job definition */
%macro extractJobCode(infile=, outfile=, debug=0);
%local/readonly DQ='22'x;
%local/readonly BSL='5c'x;
%local/readonly BS='08'x;
%local/readonly FF='0c'x;
%local/readonly NL='0a'x;
%local/readonly CR='0d'x;
%local/readonly TB='09'x;
%local/readonly SP='20'x;
data _NULL_;
attrib filein length=8 label='input file id';
attrib fileid length=8 label='output file id';
attrib stat length=8 label='State of lexical analysis';
attrib token length=$256 label='Token';
attrib ucode length=$4 label='Unicode';
attrib count length=8;
/* Open input/output files */
filein=fopen("&infile" , 'I', 1, 'B');
fileid=fopen("&outfile", 'O', 1, 'B');
count=0;
stat=0;
rec=&SP;
do while(fread(filein)=0);
rc=fget(filein, rec, 1);
%if &debug=1 %then
%do;
if count < 512 then
put stat=rec=token=;
count=count + 1;
%end;
if stat eq 0 and rec eq &DQ then
stat=1;
else if stat eq 1 then
do;
if rec eq &DQ then
do;
/* Double quotes */
if token eq 'code' then
stat=2;
else
stat=0;
token='';
end;
else
do;
token=catt(token, rec);
stat=1;
end;
end;
else if stat eq 2 then
do;
if rec in (&SP, &TB, &NL) then
stat=2;
else if rec eq ':' then
stat=3;
else
stat=0;
end;
else if stat eq 3 then
do;
if rec in (&SP, &TB, &NL) then
stat=3;
else if rec eq &DQ then
stat=4;
else
stat=0;
end;
else if stat eq 4 then
do;
if rec eq &DQ then
stat=0;
else if rec eq &BSL then
stat=5;
else
do;
rc=fput(fileid, rec);
rc=fwrite(fileid);
end;
end;
else if stat eq 5 then
do;
/* Handling of backslash-escaped characters */
if rec eq 'b' then
do;
rc=fput(fileid, &BS);
rc=fwrite(fileid);
stat=4;
end;
else if rec eq &DQ then
do;
rc=fput(fileid, &DQ);
rc=fwrite(fileid);
stat=4;
end;
else if rec eq &BSL then
do;
rc=fput(fileid, &BSL);
rc=fwrite(fileid);
stat=4;
end;
else if rec eq 'f' then
do;
rc=fput(fileid, &FF);
rc=fwrite(fileid);
stat=4;
end;
else if rec eq 'n' then
do;
rc=fput(fileid, &NL);
rc=fwrite(fileid);
stat=4;
end;
else if rec eq 'r' then
do;
rc=fput(fileid, &CR);
rc=fwrite(fileid);
stat=4;
end;
else if rec eq 't' then
do;
rc=fput(fileid, &TB);
rc=fwrite(fileid);
stat=4;
end;
else if rec eq 'u' then
do;
ucode='';
do i=1 to 4;
rc=fread(filein);
rc=fget(filein, rec, 1);
ucode=catt(ucode, rec);
end;
if ucode eq '0026' then
do;
rc=fput(fileid, '&');
rc=fwrite(fileid);
end;
else if ucode eq '003c' then
do;
rc=fput(fileid, '<');
rc=fwrite(fileid);
end;
else if ucode eq '003e' then
do;
rc=fput(fileid, '>');
rc=fwrite(fileid);
end;
else
do;
rc=fput(fileid, &BSL);
rc=fput(fileid, 'u');
rc=fput(fileid, ucode);
rc=fwrite(fileid);
end;
stat=4;
end;
end;
end;
/* Close input/output files */
rc=fclose(filein);
rc=fclose(fileid);
run;
%mend;
2022年10月12日水曜日
PROC HTTPのクエリパラメータのエンコーディング
クエリパラーメータを渡すときにエンコーディングが面倒だと思っていたら、PROC HTTPのQUERYのオプションで自動的にエンコードしてくれることに気が付いた。REST APIで日本語の名前でフィルタするときに使える。
%let name=%str(負荷テスト);
proc http url="https://%sysget(SAS_JOB_FLOW_SCHEDULING_SERVICE_HOST):443/jobFlowScheduling/flows"
query=("filter"="eq(name,'&name')")
out=outjson oauth_bearer=sas_services;
headers 'Accept'='application/vnd.sas.collection+json';
run;
2022年5月4日水曜日
SAS Viya CLI 入門 / SAS Viya REST API 入門
SAS Viya CLIの入門として資料を書き起こしました。CLIを使ってViyaのシステムを管理したい人向けです。内容を以下に示します。
- SAS Viya CLIのインストール
- プロファイル設定
- プラグインを使った操作
- OAuthプラグインでクライアントの登録
- SAS Viya CLI + jq
- curl + SAS Viya REST APIs
- SAS Viya REST API 最初に見るポイント
- SASコンテンツのフォルダ作成と権限の設定
2022年4月8日金曜日
REST APIでViya4でジョブのステータス一覧を取得する
$ export ACCESS_TOKEN=$(cat ~/.sas/credentials.json | jq -r '.Default."access-token"')
$ export URL=https://viya4.example.com/jobExecution/jobs
$ curl -k "${URL}?limit=1000&filter=and(ge(creationTimeStamp,2022-04-07),ne(state,"completed"))&orderby=endTimeStamp" -H "Authorization: Bearer $ACCESS_TOKEN" | jq -r '.items[] | [.state, .id, .jobRequest.name, .endTimeStamp, .creationTimeStamp, .modifiedTimeStamp, .elapsedTime, .createdBy, .modifiedBy, .error.message, .error.errorCode ]'
2019年2月14日木曜日
定義済みのオプションがないCASライブラリ
なんでPre-Assignの定義がないのか不思議だが、いったん放置します。
2018年11月9日金曜日
Windows PCにPython/SWATを導入して、Titanicのサンプルを実行する
インストーラに従って、Anacondaを入れます。途中でmicrosoft VSCodeを入れるか質問されましたが、スキップします。PATHを書き換えるかどうか質問されますが、これは書き換えません。複数バージョン使うために、PATHには入れないという解説がどこかにありまました。
次に、Python/SWATとDLpyをインストールします。スタートメニューにある、Anacond Promptを起動し、pipコマンドでインストールします。 具体的なコマンドは画面イメージを参照してください。
DLPyも同じようにpipコマンドで、インストールします。 もしwisted 18.7.0 requires PyHamcrest>=1.9.0, which is not installed. というようなメッセージでたら、pip install -U PyHamcrest でアップグレードしてください。
次に、サンプルのコードをGibHubから引っ張ってきます。URLは画面イメージを参照してください。右側の緑のボタンでダウンロードして、Desktopに展開します。
Windowsのスタートメニューから Jupyter Notebookを選択します。
Jupyter NotebookのFileタブから、 Desktopに展開したsas-viya-programming-master\python\titanic\TitanicExample.ipynb を開きます。
Viyaのサーバーに接続する箇所を修正します。具体的な箇所は画面イメージを参照してください。
最初のセル(import numpyの部分)を選択して、再生ボタンをポチポチおすと処理が進んでいきます。











