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で探しました。それらのホスト名とかポート番号は公式なドキュメントには書かれていないので実機検証で調べてたものです。なので内部の実装は知らぬ間に変わる可能性があることに留意してください。

CURLの--insecureに相当するのが、SSLREQCERTのオプションです。それだけだとエラーが出るので、SSLCERTLOCでPEMファイルを指定しています。

私は全く知らなかったのですが、これでPROC HTTPを実行すると接続とCOOKEの情報が保持されるそうです。それをクリアするのがコメントアウトしてある CLEAR_CACHEです。その接続とCOOKIEがあれば、毎回SSLSERTLOCを指定する必要はありません。

2023年11月4日土曜日

Androidのタブレットで、ZOOMが起動できない場合の点検箇所

Androidの端末でChromeからZoomが起動しないときの点検箇所は、PC版サイトのチェックです。また「ブラウザから参加」しようとすると、以下のようなエラーが出るときにも有効でした。

  • This site can't ask for your permission close any bubbles or overlays?
  • 他のアプリのバブルやオーバーレイをすべて閉じてから、もう一度お試しください。
試していませんが、特定サイトだけ設定というのもあるようです。

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年5月2日火曜日

デスクトップPCをリプレース, HP Pro Mini 400 G9 Desktop PC

 5年ぶりに自宅のPCをリプレースしました。これまでEliteの省スペースPCでしたが、最上位でなくても良いと思ったのでビジネス用で1ランクしたのProに乗り換えました。世代を示す番号はG3からG9に進化しています。Windows10から11への移行は面倒で、ドキュメントの位置がOne Driveとローカルで分散していたのが厄介なところです。ファイルを整理しないといけない。


ざっくりと2-3倍程度のスピードアップです。ベンチマークの結果と体感がどれだけ違うか、試してみます。

2023年4月25日火曜日

Viya4 XCMD有効化の設定

 良く忘れるのでメモ
allowXCMD がキーワード



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;