0 フォロワー · 27 投稿

プログラミングツールまたはソフトウェア開発ツールは、ソフトウェア開発者が他のプログラムやアプリケーションを作成、デバッグ、保守、またはサポートするために使用するコンピュータープログラムです。

記事 Toshihiko Minamoto · 11月 5, 2025 8m read

新しい InterSystems IRIS® Cloud SQL と InterSystems IRIS® Cloud IntegratedML® クラウド製品のユーザーであり、デプロイメントのメトリクスにアクセスして独自の可観測性プラットフォームに送信しようと考えている方のために、メトリクスを Google Cloud Platform Monitoring(旧称 StackDriver)に送信して手っ取り早く行う方法をご紹介します。

クラウドポータルには、概要メトリクス表示用のトップレベルのメトリクスが含まれており、ユーザーに公開されているメトリクスエンドポイントを使用しますが、ある程度探索しなければ、そこにあることには気づきません。

🚩 このアプローチは、「今後名前が付けられる予定の機能」を利用している可能性があるため、それを踏まえると将来性があるものではなく、確実に InterSystemsでサポートされているアプローチではありません。


では、より包括的なセットをエクスポートしたい場合はどうでしょうか?この技術的な記事/例では、メトリクスを取得して可観測性に転送する方法を紹介します。Open Telemetry Collector を使用して、任意のメトリクスターゲットを取得し、任意の可観測性プラットフォーム送信できるように、ニーズに合わせて変更することができます。

上記の結果に導く仕組みは多数の方法で得られますが、ここでは Kubernetes pod を使用して、1 つのコンテナーで Python スクリプトを実行し、もう 1 つのコンテナーで Otel を実行して、メトリクスのプルとプッシュを行います... 自分のやり方を選択することはできますが、この例と記事では、k8s を主人公に Python を使って行います。

手順:

  • 前提条件
  • Python
  • コンテナー
  • Kubernetes
  • Google Cloud Monitoring

前提要件:

  • IRIS®  Cloud SQL の有効なサブスクリプション
  • 実行中の 1 つのデプロイメント(オプションで Integrated ML を使用)
  • 環境に提供するシークレット

環境変数

 
 シークレットの取得
この内容は少し複雑で本題から少し外れているためティーザーに入れましたが、これがシークレットの生成に必要なる値です。
ENV IRIS_CLOUDSQL_USER 'user'
ENV IRIS_CLOUDSQL_PASS 'pass'

☝ これは https://portal.live.isccloud.io の認証情報です。

ENV IRIS_CLOUDSQL_USERPOOLID 'userpoolid'
ENV IRIS_CLOUDSQL_CLIENTID 'clientid'
ENV IRIS_CLOUDSQL_API 'api'

☝ これはブラウザの開発ツールから取得する必要があります。

  • `aud` = clientid
  • `userpoolid`= iss
  • `api` = request utl

ENV IRIS_CLOUDSQL_DEPLOYMENTID 'deploymentid'

☝これはクラウドサービスポータルから取得できます

 

Python:

以下に、クラウドポータルからメトリクスを取得し、それを Otel Collectorが取得するメトリクスとしてローカルにエクスポートする Python ハッキングを示します。

 
iris_cloudsql_exporter.py
import time
import os
import requests
import json

from warrant import Cognito from prometheus_client.core import GaugeMetricFamily, REGISTRY, CounterMetricFamily from prometheus_client import start_http_server from prometheus_client.parser import text_string_to_metric_families

classIRISCloudSQLExporter(object):definit(self): self.access_token = self.get_access_token() self.portal_api = os.environ['IRIS_CLOUDSQL_API'] self.portal_deploymentid = os.environ['IRIS_CLOUDSQL_DEPLOYMENTID']

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">collect</span><span class="hljs-params">(self)</span>:</span>
    <span class="hljs-comment"># Requests fodder</span>
    url = self.portal_api
    deploymentid = self.portal_deploymentid
    print(url)
    print(deploymentid)

    headers = {
        <span class="hljs-string">'Authorization'</span>: self.access_token, <span class="hljs-comment"># needs to be refresh_token, eventually</span>
        <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>
    }

    metrics_response = requests.request(<span class="hljs-string">"GET"</span>, url + <span class="hljs-string">'/metrics/'</span> + deploymentid, headers=headers)
    metrics = metrics_response.content.decode(<span class="hljs-string">"utf-8"</span>)

    <span class="hljs-keyword">for</span> iris_metrics <span class="hljs-keyword">in</span> text_string_to_metric_families(metrics):
        <span class="hljs-keyword">for</span> sample <span class="hljs-keyword">in</span> iris_metrics.samples:

            labels_string = <span class="hljs-string">"{1}"</span>.format(*sample).replace(<span class="hljs-string">'\''</span>,<span class="hljs-string">"\""</span>)
            labels_dict = json.loads(labels_string)
            labels = []

            <span class="hljs-keyword">for</span> d <span class="hljs-keyword">in</span> labels_dict:
                labels.extend(labels_dict)
            <span class="hljs-keyword">if</span> len(labels) &gt; <span class="hljs-number">0</span>:
                g = GaugeMetricFamily(<span class="hljs-string">"{0}"</span>.format(*sample), <span class="hljs-string">'Help text'</span>, labels=labels)
                g.add_metric(list(labels_dict.values()), <span class="hljs-string">"{2}"</span>.format(*sample))
            <span class="hljs-keyword">else</span>:
                g = GaugeMetricFamily(<span class="hljs-string">"{0}"</span>.format(*sample), <span class="hljs-string">'Help text'</span>, labels=labels)
                g.add_metric([<span class="hljs-string">""</span>], <span class="hljs-string">"{2}"</span>.format(*sample))
            <span class="hljs-keyword">yield</span> g

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_access_token</span><span class="hljs-params">(self)</span>:</span>
    <span class="hljs-keyword">try</span>:
        user_pool_id = os.environ[<span class="hljs-string">'IRIS_CLOUDSQL_USERPOOLID'</span>] <span class="hljs-comment"># isc iss </span>
        username = os.environ[<span class="hljs-string">'IRIS_CLOUDSQL_USER'</span>]
        password = os.environ[<span class="hljs-string">'IRIS_CLOUDSQL_PASS'</span>]
        clientid = os.environ[<span class="hljs-string">'IRIS_CLOUDSQL_CLIENTID'</span>] <span class="hljs-comment"># isc aud </span>
        print(user_pool_id)
        print(username)
        print(password)
        print(clientid)
        
        <span class="hljs-keyword">try</span>:
            u = Cognito(
                user_pool_id=user_pool_id,
                client_id=clientid,
                user_pool_region=<span class="hljs-string">"us-east-2"</span>, <span class="hljs-comment"># needed by warrant, should be derived from poolid doh</span>
                username=username
            )
            u.authenticate(password=password)
        <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> p:
            print(p)
    <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
        print(e)

    <span class="hljs-keyword">return</span> u.id_token

ifname == 'main':

start_http_server(<span class="hljs-number">8000</span>)
REGISTRY.register(IRISCloudSQLExporter())
<span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:
    REGISTRY.collect()
    print(<span class="hljs-string">"Polling IRIS CloudSQL API for metrics data...."</span>)
    <span class="hljs-comment">#looped e loop</span>
    time.sleep(<span class="hljs-number">120</span>)</code></pre>

 

Docker:

 
Dockerfile
FROM python:3.8ADD src /src
RUN pip install prometheus_client
RUN pip install requests
WORKDIR /src
ENV PYTHONPATH '/src/'ENV PYTHONUNBUFFERED=1ENV IRIS_CLOUDSQL_USERPOOLID 'userpoolid'ENV IRIS_CLOUDSQL_CLIENTID 'clientid'ENV IRIS_CLOUDSQL_USER 'user'ENV IRIS_CLOUDSQL_PASS 'pass'ENV IRIS_CLOUDSQL_API 'api'ENV IRIS_CLOUDSQL_DEPLOYMENTID 'deploymentid'RUN pip install -r requirements.txt
CMD ["python" , "/src/iris_cloudsql_exporter.py"]
docker build -t iris-cloudsql-exporter .
docker image tag iris-cloudsql-exporter sween/iris-cloudsql-exporter:latest
docker push sween/iris-cloudsql-exporter:latest


デプロイメント:

k8s、ネームスペースを作成します:

kubectl create ns iris

k8s、シークレットを追加します:

kubectl create secret generic iris-cloudsql -n iris \
    --from-literal=user=$IRIS_CLOUDSQL_USER \
    --from-literal=pass=$IRIS_CLOUDSQL_PASS \
    --from-literal=clientid=$IRIS_CLOUDSQL_CLIENTID \
    --from-literal=api=$IRIS_CLOUDSQL_API \
    --from-literal=deploymentid=$IRIS_CLOUDSQL_DEPLOYMENTID \
    --from-literal=userpoolid=$IRIS_CLOUDSQL_USERPOOLID

otel、構成を作成します:

apiVersion: v1
data:
  config.yaml: |
    receivers:
      prometheus:
        config:
          scrape_configs:
          - job_name: 'IRIS CloudSQL'
              # Override the global default and scrape targets from this job every 5 seconds.
            scrape_interval: 30s
            scrape_timeout: 30s
            static_configs:
                    - targets: ['192.168.1.96:5000']
            metrics_path: /
exporters:
  googlemanagedprometheus:
    project: "pidtoo-fhir"
service:
  pipelines:
    metrics:
      receivers: [prometheus]
      exporters: [googlemanagedprometheus]

kind: ConfigMap metadata: name: otel-config namespace: iris

k8s、otel 構成を configmap としてロードします:

kubectl -n iris create configmap otel-config --from-file config.yaml

k8s、ロードバランサー(確実にオプション)、MetalLB をデプロイします。これはクラスタ外部からグスクレイピングして検査するために行っています。

cat <<EOF | kubectl apply -f -n iris -
apiVersion: v1
kind: Service
metadata:
  name: iris-cloudsql-exporter-service
spec:
  selector:
    app: iris-cloudsql-exporter
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 5000
    targetPort: 8000
EOF

gcp、Google Cloud へのキーが必要です。サービスアカウントにスコープを設定する必要があります

  • roles/monitoring.metricWriter
kubectl -n iris create secret generic gmp-test-sa --from-file=key.json=key.json

k8s; deployment/pod そのもの。2 つのコンテナー:

 
deployment.yaml
kubectl -n iris apply -f deployment.yaml

実行

特に問題がなければ、ネームスペースを詳しく調べて、状況を確認してみましょう。

✔ GCP と Otel 用の 2 つの configmap

 

✔ 1 つのロードバランサー

 

✔ 1 つの pod、2 つのコンテナーが正しくスクレイピングされます

  

Google Cloud Monitoring

可観測性を調べてメトリクスが正しく受信されていることを確認し、可観測性を高めましょう!

 

0
0 20
お知らせ Toshihiko Minamoto · 10月 14, 2025

%UnitTestフレームワークのユーザーは、InterSystems Testing Manager拡張機能の最新リリース(v2.0.0)を@Timothy Leavittの素晴らしいテストカバレッジツールと組み合わせることで、VS Code内でテストカバレッジ情報を取得できるようになりました。

上部にテストカバレッジのペインが表示されています。左側のテストエクスプローラーと併せて確認しやすいように、右側のセカンダリサイドバーに移動させました。

直近のテスト実行(テストカバレッジツール自体のユニットテストすべて)の結果、TestCoverage.Procedures内のBitValueメソッドはカバーされていましたが、BitCountメソッド(および他の6つのメソッド)はカバーされていないことに注目してください。 TestCoverageパッケージの全体で43.08%の実行可能行のみが、ユニットテストによってカバーされていました。

InterSystems Testing Managerに対するこの大幅なアップグレードを、現在開催中のDeveloper Toolsコンテスト に出品します。 もし良いと思っていただけたら、来週の投票でぜひ応援してください!

0
0 29
記事 Toshihiko Minamoto · 10月 7, 2025 9m read

コミュニティの皆さん、こんにちは。
この記事では、私のアプリケーションである iris-AgenticAI をご紹介します。

エージェンティック AI の登場により、人工知能が世界とやりとりする方法に変革的な飛躍をもたらし、静的なレスポンスが動的な目標主導の問題解決にシフトしています。 OpenAI の Agentic SDK を搭載した OpenAI Agents SDK を使用すると、抽象化をほとんど行わずに軽量で使いやすいパッケージでエージェンティック AI アプリを構築できます。 これは Swarm という前回のエージェントの実験を本番対応にアップグレードしたものです。
このアプリケーションは、人間のような適応性で複雑なタスクの推論、コラボレーション、実行を行える次世代の自律 AI システムを紹介しています。

アプリケーションの機能

  • エージェントループ  🔄 ツールの実行を自律的に管理し、結果を LLM に送信して、タスクが完了するまで反復処理するビルトインのループ。
  • Python-First 🐍 ネイティブの Python 構文(デコレーター、ジェネレーターなど)を利用して、外部の DSL を使用せずにエージェントのオーケストレーションとチェーンを行います。
  • ハンドオフ 🤝 専門化されたエージェント間でタスクを委任することで、マルチエージェントワークフローをシームレスに調整します。
  • 関数ツール ⚒️ @tool で Python 関数をデコレートすることで、エージェントのツールキットに即座に統合させます。
  • ベクトル検索(RAG) 🧠 RAG 検索のためのベクトルストアのネイティブ統合。
  • トレース 🔍 リアルタイムでエージェントワークフローの可視化、デバッグ、監視を行うためのビルトインのトレース機能(LangSmith の代替サービスとして考えられます)。
  • MCP サーバー 🌐 stdio と HTTP によるモデルコンテキストプロトコル(MCP)で、クロスプロセスエージェント通信を可能にします。
  • Chainlit UI 🖥️ 最小限のコードで対話型チャットインターフェースを構築するための統合 Chainlit フレームワーク。
  • ステートフルメモリ 🧠 継続性を実現し、長時間実行するタスクに対応するために、セッション間でチャット履歴、コンテキスト、およびエージェントの状態を保持します。

エージェント

エージェントは、アプリの主要な構成要素です。 エージェントは大規模言語モデル(LLM)で、instructions と tools で構成されています。 基本的な構成 以下は、構成されるエージェントの最も一般的なプロパティです。

Instructions: 開発者メッセージまたはシステムプロンプトとも呼ば出る指示。
model: LLM が使用するモデル。オプションとして model_settings を使用して、temperature や top_p など、モデルのチューニングパラメーターを構成できます。
tools: タスクを達成するためにエージェントが使用できるツール。

from agents import Agent, ModelSettings, function_tool

@function_tooldefget_weather(city: str) -> str:returnf"The weather in {city} is sunny"
agent = Agent(
    name="Haiku agent",
    instructions="Always respond in haiku form",
    model="o3-mini",
    tools=[get_weather],
)

エージェントの実行

Runner クラスを使ってエージェントを実行できます。 これには 3 つのオプションがあります。

  1. Runner.run(): 非同期で実行し、RunResult を返します。
  2. Runner.run_sync(): 非同期メソッドで、内部で .run() を実行します。
  3. Runner.run_streamed(): 非同期で実行し、RunResultStreaming を返します。 ストリーミングモードで LLM を呼び出し、イベントを受け取るたびにユーザーにストリーミングします。
from agents import Agent, Runner

asyncdefmain(): agent = Agent(name="Assistant", instructions="You are a helpful assistant")

result = <span class="hljs-keyword">await</span> Runner.run(agent, <span class="hljs-string">"Write a haiku about recursion in programming."</span>)
print(result.final_output)
<span class="hljs-comment"># Code within the code,</span>
<span class="hljs-comment"># Functions calling themselves,</span>
<span class="hljs-comment"># Infinite loop's dance.</span></code></pre>


エージェントアーキテクチャ

アプリケーションは 7 つの専門化されたエージェントで構成されています。

  1. Triage エージェント 🤖
    • 機能: ユーザー入力を受け取り、ハンドオフでタスクを委任する主要ルーター
    • : 「Show production errors(プロダクションエラーを表示)」は IRIS プロダクションエージェントに転送されます。
  2. ベクトル検索エージェント 🤖
    • 機能: IRIS 2025.1 リリースノートの内容を提供します(RAG 機能)
    • : 「Provide me summary of Release Notes(リリースノートの要約を提供)」はベクトル検索エージェントに転送されます。
  3. IRIS Dashboard エージェント 🤖
    • 機能: リアルタイムの管理ポータルメトリクスを提供します: plaintext Copy
      ApplicationErrors, CSPSessions, CacheEfficiency, DatabaseSpace, DiskReads,  
      DiskWrites, ECPAppServer, ECPDataServer, GloRefs, JournalStatus,  
      LicenseCurrent, LockTable, Processes, SystemUpTime, WriteDaemon, [...]
  4. IRIS 実行プロセスエージェント 🤖
    • 機能: アクティブなプロセスを次の詳細とともに監視します。
      • Process ID | Namespace | Routine | State | PidExternal
  5. IRIS Production エージェント 🤖
    • 機能: プロダクションの開始と停止の機能とともにプロダクションの詳細を提供します。
  6. WebSearch エージェント 🤖
    • 機能: API 統合によりコンテキストウェブ検索を実行します。
  7. Order エージェント 🤖
    • 機能: 注文 ID を使用して注文のステータスを取得します。


ハンドオフ

ハンドオフによって、タスクを別のエージェントに委任することができます。 これは特に、それぞれのエージェントが異なる分野に特化している場合に役立ちます。 たとえば、カスタマーサポートアプリには、注文ステータス、返金、FAQ などのそれぞれのタスクを専門的に処理するエージェントが実装されている場合があります。

Triage エージェントはこのアプリケーションのメインエージェントで、ユーザー入力に基づいて別のエージェントにタスクを委任するエージェントです。

#TRIAGE AGENT, Main agent receives user input and delegates to other agent by using handoffs
    triage_agent = Agent(
        name="Triage agent",
        instructions=(
            "Handoff to appropriate agent based on user query.""if they ask about Release Notes, handoff to the vector_search_agent.""If they ask about production, handoff to the production agent.""If they ask about dashboard, handoff to the dashboard agent.""If they ask about process, handoff to the processes agent.""use the WebSearchAgent tool to find information related to the user's query and do not use this agent is query is about Release Notes.""If they ask about order, handoff to the order_agent."
        ),
        handoffs=[vector_search_agent,production_agent,dashboard_agent,processes_agent,order_agent,web_search_agent]
    )


トレース

Agents SDK には、トレース機能が組み込まれており、エージェントの実行中にLLM の生成、ツールの呼び出し、ハンドオフ、ガードレール、カスタムイベントの発生など、イベントの包括的な記録を収集できます。 Traces ダッシュボードを使用すると、開発中と本番稼動時にワークフローのデバッグ、可視化、監視を行えます。
https://platform.openai.com/logs

image

 


アプリケーションのインターフェース

アプリケーションのワークフロープロセス
ベクトル検索エージェント

ベクトル検索エージェントは、「New in InterSystems IRIS 2025.1」のテキスト情報のデータがまだ存在しない場合に、そのデータを一度だけ自動的に IRIS Vector Store に取り込みます。  


以下のクエリを使用してデータを検索しましょう

SELECTid, embedding, document, metadata
FROM SQLUser.AgenticAIRAG

Triage エージェントはユーザー入力を受け取って、質問をベクトル検索エージェントに転送します。

IRIS Dashboard エージェント

Triage エージェントはユーザー入力を受け取って、質問を IRIS Dashboard エージェントに転送します。

IRIS Processes エージェント

Triage エージェントはユーザー入力を受け取って、質問を IRIS Processes エージェントに転送します。

IRIS Production エージェント

Production エージェントを使用して、プロダクションの開始と停止を行います。

Production エージェントを使用して、プロダクションの詳細を取得します。

Local エージェント

Triage エLocal ージェントはユーザー入力を受け取って、質問を Local Order エージェントに転送します。

WebSearch エージェント

ここでは、Triage エージェントは 2 つの質問を受け取って、WebSearch エージェントに転送します。

MCP Server アプリケーション

MCP Server は https://localhost:8000/sse で実行しています。

image
以下のコードで MCP Server を起動しています。

import os
import shutil
import subprocess
import time
from typing import Any
from dotenv import load_dotenv

load_dotenv()

#Get OPENAI Key, if not fond in .env then get the GEIMINI API KEY#IF Both defined then take OPENAI Key openai_api_key = os.getenv("OPENAI_API_KEY") ifnot openai_api_key: raise ValueError("OPENAI_API_KEY is not set. Please ensure to defined in .env file.")

ifname == "main": # Let's make sure the user has uv installedifnot shutil.which("uv"): raise RuntimeError( "uv is not installed. Please install it: https://docs.astral.sh/uv/getting-started/installation/" )

<span class="hljs-comment"># We'll run the SSE server in a subprocess. Usually this would be a remote server, but for this</span>
<span class="hljs-comment"># demo, we'll run it locally at http://localhost:8000/sse</span>
process: subprocess.Popen[Any] | <span class="hljs-keyword">None</span> = <span class="hljs-keyword">None</span>
<span class="hljs-keyword">try</span>:
    this_dir = os.path.dirname(os.path.abspath(__file__))
    server_file = os.path.join(this_dir, <span class="hljs-string">"MCPserver.py"</span>)

    print(<span class="hljs-string">"Starting SSE server at http://localhost:8000/sse ..."</span>)

    <span class="hljs-comment"># Run `uv run server.py` to start the SSE server</span>
    process = subprocess.Popen([<span class="hljs-string">"uv"</span>, <span class="hljs-string">"run"</span>, server_file])
    <span class="hljs-comment"># Give it 3 seconds to start</span>
    time.sleep(<span class="hljs-number">3</span>)

    print(<span class="hljs-string">"SSE server started. Running example...\n\n"</span>)
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
    print(<span class="hljs-string">f"Error starting SSE server: <span class="hljs-subst">{e}</span>"</span>)
    exit(<span class="hljs-number">1</span>)

 

MCP Server には次のツールが備わっています。

  • IRIS 2025.1 リリースノートの詳細を提供(ベクトル検索)
  • IRIS 情報ツール
  • 天気チェックツール
  • シークレットワードの検索ツール(ローカル関数)
  • 加算ツール(ローカル関数)

MCP アプリケーションは  http://localhost:8001で実行しています。

 

MCP Server ベクトル検索(RAG)機能

MCP Server には InterSystems IRIS ベクトル検索インジェスト機能と検索拡張生成(RAG)機能が備わっています。


MCP Server の他の機能

MCP Server は、ユーザー入力に基づいて、適切なツールに動的にタスクを委任します。


詳細については、iris-AgenticAI の Open Exchange アプリケーションページをご覧ください。

以上です

0
0 26
お知らせ Toshihiko Minamoto · 8月 13, 2024

%UnitTest framework を使用してユニットテストを構築したことがある場合、またはこれから構築しようとお考えの場合は、InterSystems Testing Manager をご覧ください。

VS Code を離れることなく、ユニットテストの閲覧、実行またはデバッグ、過去の実行結果の表示が可能になりました。

InterSystems Testing Manager は、ObjectScript 拡張機能がサポートするソースコード場所のパラダイムに対応しています。 ユニットテストクラスは、VS Code のローカルファイルシステム('client-side editing' パラダイム)またはサーバーネームスペース('server-side editing')のいずれかでマスターできます。 いずれの場合でも、実際のテストの実行は、サーバーネームスペースで発生します。

フィードバックをぜひお送りください。

0
0 76
記事 Toshihiko Minamoto · 3月 18, 2024 7m read

はじめに

InterSystems は先日、Visual Studio Code(VSC)IDE 用の拡張機能は InterSystems Studio に比べてより優れたエクスペリエンスを提供するという考えから、VSC IDE 用の拡張機能を独占的に開発するためにバージョン 2023.2 より InterSystems Studio のサポートを終了すると発表しました。それ以来、VSC に切り替えた開発者や、VSC を使用し始めた開発者が大勢います。 VSC には Studio のような出力パネルがなく、InterSystems が開発したプラグインをダウンロードする以外に IRIS ターミナルを開く統合機能もないため、多くの人は演算を実行する際にターミナルの開き方に迷ったことでしょう。

概要

  • はじめに 
  • 解決策
    • 少なくとも IRIS 2020.1 または IRIS 2021.1.2 を使用するユーザー: Web ターミナルを使用
    • 少なくとも least IRIS 2023.2 を使用するユーザー: WebSocket ターミナルを使用
    • Docker ベースの IRIS を使用するユーザー
    • ローカルマシンでバージョン 2023.2 より前の IRIS を使用するユーザー
    • SSH 接続を使ってリモートサーバーの IRIS でコーディングするユーザー

解決策

VSC でターミナルを開く方法は使用している特定の構成によって異なるため、以下に、状況に最適な解決策をまとめました。

少なくとも IRIS 2020.1.1 または IRIS 2021.1.2 を使用するユーザー: Web ターミナルを使用

少なくとも IRIS 2020.1.1 または IRIS 2021.1.2 を使用し、外部の拡張機能のインストールが許可されている(サードパーティアプリケーションに関する会社のポリシーにより許可されていない場合もあります)ユーザーの場合、VSC 用の Web ターミナル拡張機能が役立つ可能性があります。 ご存知ない方のために説明すると、Web ターミナルは、ObjectScript で制作された InterSystems 製品(IRIS、Caché、Ensemble、HealthShare、TrakCare など)用の Web ベースのターミナルで、ブラウザ内でより高度なバージョンのターミナルを使用することができます(プロジェクトページはこちらです)。 この VSC 拡張機能によって、直接 VSC からクリックするだけで Web ベースのターミナルを起動できます。

Web ターミナルを開くには、InterSystems ツール をクリックし、ネームスペースを選択して、いずれかのアイコン( または )をクリックします。それぞれ、VSC ターミナルパネルかブラウザで Web ターミナルが開きます(Alt を押すとデフォルトアイコンを変更できます)。

 

 

少なくとも least IRIS 2023.2 を使用するユーザー: WebSocket ターミナルを使用

少なくとも IRIS 2023.2 を使用するユーザーは、最新バージョンの VSC 拡張機能に含まれる新しい「WebSocket ターミナル」機能を利用できるため、他の回避策は必要ありません。

WebSocket ターミナルを開くには、InterSystems ツールをクリックし、ネームスペースを選択して、Web ターミナルの隣のアイコンをクリックします。

編集: 詳細については、これについて @Brett Saviano が書いたおもしろい記事をご覧ください!

How to run ObjectScript commands in the VS Code integrated terminal(VS Code の統合ターミナルで ObjectScript コマンドを実行する方法)

Docker ベースの IRIS を使用するユーザー

Docker 内の IRIS 環境で作業しており、VSC を使用しているユーザーは、Docker 環境から直背悦ターミナルセッションを開始できます。

ステータスバーで Docker voice をクリックし、Docker でターミナルを開くを選択します。

このポイントについて画像と説明を提供してくれた @Evgeny Shvarov に感謝しています。

 

ローカルマシンでバージョン 2023.2 より前の IRIS を使用するユーザー

ローカルマシンで実行するバージョンの IRIS で作業するユーザーの場合は、VSC 内に専用の IRIS ターミナルをセットアップすることができます。

    1. settings.json ファイルを開きます。 このファイルを見つけるには、表示 > コマンドパレットをクリックして「settings」と入力し、ユーザー設定を開く(JSON)を選択するなど、様々な方法があります。
    2. terminal.integrated.profiles.windows」の下に以下のコードを追加します。
"terminal.integrated.profiles.windows":{
<span class="hljs-string">"IRIS Terminal"</span>: {

&nbsp;&nbsp;&nbsp; <span class="hljs-string">"path"</span>: [

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="hljs-string">"C:\\InterSystems\\IRISHealth\\bin\\irissession.exe"</span>
&nbsp;&nbsp;&nbsp; ],

&nbsp;&nbsp;&nbsp; <span class="hljs-string">"args"</span>: [<span class="hljs-string">"IRISHEALTH"</span>],

&nbsp;&nbsp;&nbsp; <span class="hljs-string">"icon"</span>: <span class="hljs-string">"terminal-cmd"</span>
} 

}

注意: 正しい irissession.exe のパスを挿入してください。

c. VSC からターミナルを開くには、ターミナル > 新しいターミナル > プロファイルを起動… > IRIS ターミナルに移動します。

d. ターミナルメニューに 'IRIS ターミナル' voice が表示されます。

SSH 接続を使ってりモードサーバーの IRIS でコーディングするユーザー 

SSH 接続(PuTTY の使用など)を使ってアクセスできるリモートサーバー(会社サーバーなど)の IRIS バージョンを使用するユーザーの場合、Remote - SSH VSC 拡張機能を使用して、VSC をサーバーに直接接続できます。 これを行うには、以下を実行します。

    1. VSC に Remote - SSH: Editing Configuration Files 拡張機能をインストールします。
    2. サイドバーの「リモートエクスプローラーアイコンをクリックします。
    3. SSH 構成ファイルを開く」を選択します。

  

次のパスの構成ファイルを開きます: C:\Users\<username>\.ssh\config

    1. 構成ファイルに以下のコードを挿入します。 
Host my-putty-connection

    HostName < IP address or server name >

    User < username >

    IdentityFile < private key path on your local machine >

    Port < port >

IP アドレスとポートは PuTTY に指定されたホスト名とポート、ユーザー名はリモートサーバーにアクセスする際に使用するユーザー認証情報、そして IdentityFile は PuTTY 秘密鍵へのファイルパスです。

注意:  PuTTY が生成した秘密鍵の元のフォーマット(.ppk)は VSC で読み取れません。 PuTTY 経由で VSC とリモートサーバーの接続を確立するには、元の秘密鍵を複製して .pem フォーマットに変換する必要があります。 この変換は、以下のように行います。

  1. PuTTYgen アプリケーションを起動します。
  2. File メニューから、Load private key をクリックします。
  3. .ppk フォーマットの秘密鍵を選択して、Open を選択します。
  4. Conversions メニューで Export OpenSSH Key (force new file format) をクリックします。
  5. .pem 拡張子を使った新しい名前を設定し、Save ボタンをクリックします。
  6. この新しい .pem ファイルへのパスを VSC の IdentifyFile パラメーターにリンクします。
    1. ファイルを保存します。 数秒ほどすると、Remote Explorer パネルに新しい接続が表示されます。
    2. Connect in New Window...」をクリックして新しい VSC ウィンドウに SSH 接続を開きます。
  7. リモートマシンのオペレーティングシステムを選択します(初回アクセスのみ)。
  8. 新しいウィンドウで、Terminal New Terminal に移動します(または Ctrl + ò または Ctrl + Shift + ò を使用します)。
  9. これで、リモートマシンに接続し、VSC 内で IRIS ターミナルを使用できるようになりました。

注意: この操作は、以前に PuTTY 経由でリモート接続を開始したことがあり、PuTTY が閉じられている場合またはリモートサーバーに接続していない場合にのみ機能します。 この操作では、PuTTY は起動せず、PuTTY が確立するトンネルに VSC が接続されるだけです。

VSC を通じて PuTTY 接続を開始するには、バッチファイルを使用できます(Windows)。 提供されている connect_remote.bat ファイルは、PuTTY に含まれる Plink コマンドを使用してセッションを開始します。

@echo off

set SESSION="<your saved session name>"

plink -load %SESSION%

セッションを開始するには、VSC ターミナルに .\connect_remote.bat と入力して、リモート接続を開き、認証情報を入力します。

注意: こちらの後のメソッドによって、すべての VSC ショートカットをサポートするターミナルバージョンにアクセスできるようになります! Shift+Insert ではなく、Ctrl+V を使用できるようになります 🎉

1
1 611
記事 Toshihiko Minamoto · 2月 29, 2024 6m read

コミュニティの皆さん、こんにちは!

この記事では、私の最新のアプリケーションである Journal File Indexer をご紹介します。 このアプリケーションの開発は、ポータルアイデアの DPI-I-270 に基づいています。

簡単に言えば、このアプリケーションではデータベースでログファイルを読み込んでインデックス作成できます。

製作理由

管理ポータルでログファイルの検索機能を使用したことがあるなら、タイムアウトエラーになったり、ページが空になったりしたことがあるのではないでしょうか。 この問題は通常、大規模なジャーナルファイルを検索する場合に発生します。 Journal File Indexer は、ファイルをデータベースに読み込んで、検索速度を大幅に高めることで、この問題を解決します。

復元プロセス中にはもう 1 つの問題が発生します。 ログファイルでグローバルエントリを検索し、古い値または新しい値を復元したくても、管理ポータルにはこの特定の機能がありません。 そのため、これを達成するにはルーチンをコーディングする必要があります。 Journal File Indexer を使うと、この復元機能を統合できます!

アーキテクチャ

最新の開発標準を使用したため、このアプリケーションはフロントエンドの Angular、当然ながらバックエンドの ObjectScript、REST API、JWT 認証、および WebSocket で構成されています。

注意: サーバーサイドの REST API は OpenAPI-Suite を使って Swagger 仕様から生成されています。

ストレージについて

インデックス作成されたログデータは「一時データ」と見なされるため、デフォルトで IRISTEMP に保存されます。 この動作は、単純なグローバルマッピングによって簡単に変更可能です(次のセクションを参照)。

アプリケーションの実行

アプリケーションは 2 つあります。1 つはバックエンド用で、もう 1 つはフロントエンド用です。そのため、最も簡単な方法は Docker を使用することです。

Docker の使用

git clone https://github.com/lscalese/journal-file-indexer.git
cd journal-file-indexer
docker-compose up -d

# イメージを再作成する必要がある場合:# docker-compose build --no-cache

そして、http://localhost:8090/login を開きます。

 

Docker 以外のユーザー

IPM を使ってバックエンドアプリケーションをインストールするには、以下のコマンドを実行します。

zpm "install journal-indexer"

フロントエンドの場合は、Web サーバーで "URL rewrite" モジュールと WebSocket 機能が有効であることを確認します。 コンパイルされた Angular アプリケーションは "dist" フォルダにあります。 "journal-indexer-ui" をホストするように Web サーバーインスタンスを構成します。事前にビルドされた Angular アプリケーションを使うと、暗黙的に Web ゲートウェイと同じ Web サーバーインスタンスにそれをホストしていることになります。

注意:  IIS ユーザーの場合、デフォルトの構成ファイルは、URL 書き換えルールと WebSocket が有効な状態で提供されます(web.config ファイルを参照)。

別の環境パラメーターを使ってフロントエンドアプリケーションをビルドし直す必要がある場合は、こちらのリポジトリにアクセスしてください。提供されているビルド済みバージョンでは、以下のコマンドが使用されています。

ng build --configuration=webgateway

独自の特定の要件に従って自由に新しい環境を作成し、アプリケーションをビルドできます。

機能

この記事にはすべての詳細な機能を含めてはいませんが、近日デモ動画を作成する予定です。 フロントエンドアプリケーションは、単純で使いやすく設計されています。

基本的に、Journal Indexer は、ダウンロード、インデックス作成、統計表示、検索、ログファイルからのデータの復元を行うための Web インターフェースを備えています。

「New」または「Load」メニューに移動して、ログファイルのインデックスを作成することから始め、そこから、利用できるその他のさまざまな機能を詳しくご覧ください。

以下は、スクリーンショットです。

 

  

Journal Indexer には、ターミナルアプリケーションも備わっています。

Do^JRNINDEXER

このプロジェクトの主な焦点はターミナルアプリケーションを橋梁するものではありませんが、興味のある方は README.md ファイルで詳細をご覧ください。

注意事項

Journal File Indexer では IRISTEMP データベースを使ってデータを保存しています。インスタンスを再起動すると、インデックス作成されたデータは失われます。

ジャーナルファイルのインデックス作成には空き容量が必要で、たとえば、1 GB のサイズのジャーナルファイルの場合、IRISTEMP の最大 5GB が必要となることがあります。そのため、IRISTEMP ディスクに十分な空き容量を確保してください。

別のデータベースにデータを保存したい場合は、"^IRIS.Temp.data.*" にグローバルマッピングを作成できます。ミラー環境では、ミラーのデータベースを選択すると、ジャーナルファイルのインデックス作成によって大量のジャーナルレコードが生成されることに注意してください(IRISTEMP ではこの動作はありません)。

ディスクストレージの高使用率を回避するために、Journal Indexer はインデックス作成済みジャーナルを 5 個しか保持しません。6 番目ジャーナルをインデックス作成すると、最も古いものが自動的に IRISTEMP から削除されます。

この制限は、以下のクラスメソッドを使って調整できます。

; ex: to keep 7 indexed journalsDo##class(dc.journalindexer.services.Config).SetMaxJournalRetention(7)

さらに、個人的な意見としては、この種のツールを実稼動システムに直接インストールするのはお勧めしません。 Journal File Indexer では外部ログファイルのアップロードを簡単に行えます。 このツールは、テストシステムで使用してから、必要に応じてデータをエクスポートすることをお勧めします。

プロジェクト環境について

この開発プロジェクトへの取り組みは、楽しくもありながら、チャレンジを要するものでもありました。 これは私が初めて Andular を使ってフロントエンドアプリケーションを作成したプロジェクトであったため、学習とプロジェクトのビルドの過程で多くのことが得られました。

バックエンド開発も、REST API の生成、インデックス作成の進捗を通知する Web ソケットの組み込み、カスタムクラスクエリの作成、ターミナルモードでインデックス作成の進捗を通信するための $SYSTEM.Event の使用、メモリ操作、カスタムストレージソリューションの実装、ユニットテスト、および Journal API の利用が伴い、同じようにやりがいのある作業ででした。

QuinielaML をご提供いただいた @Luis Angel Pérez Ramos(フロントエンドアプリケーションの類似部分が役立ちました)、レビューしていただいた @Dmitry Maslennikov、およびアイデアを実装する気にさせてくれた @Vadim Aniskin に感謝しています!

0
0 143
記事 Toshihiko Minamoto · 5月 2, 2023 6m read

開発者のみなさん、こんにちは。

vscode上で動作するObjectScriptエクステンションがリリースされ、vscodeを開発環境として使用できるようになり、GitHubリポジトリと連携できるようになりました。その一方で、使い慣れたIRISやCacheのスタジオからGitHubを扱いたいという要望は根強くあり、GitHubと連携するツールがOpen Exchange上にいくつか公開されています。

そこで、Open exchangeに収録されているツールの中で新しい「git for shared development environment」を使い、環境を作成してみましたので、その手順をお伝えします。

ご利用される際のご参考になれば幸いです。

Git for windows のインストール

Git for windows のサイト よりキットをダウンロードし、そのexeファイル (git-2.xx.xx xx-bit.exe) を起動します。ライセンスの確認画面が表示されますので、「Install」ボタンをクリックします。

 

SSHキーペアの作成

コマンドプロンプトを起動し、ssh-keygen コマンドを実行します。

1
0 364
記事 Mihoko Iijima · 2月 16, 2023 2m read

開発者の皆さん、こんにちは!

InterSystems デベロッパーツールコンテスト2023 の21の応募作品の中から、Experts Nomination 第2位に輝いた @John Murray  さんの DX Jetpack for VS Code (VSCodeを使用するIRIS開発者のエクスペリエンスを向上させるツール)についてご紹介します。

開発された @John Murray さんが書かれた記事「Introducing DX Jetpack for VS Code」には、3つの新しいエクステンションについて紹介されていますが、ここでは、gj :: codeSpex と ObjectScript Class View の使用例をご紹介します。

まずは、VSCodeをご用意ください。

Extentionの検索窓で、gj と入力する以下の表示になります。

この中から、をインストールしてみました。

試しにクラス定義を作成してみたところ、行番号右隣に吹き出しのマークが登場し、クリックするとクラス定義で使用しているデータタイプの解説が表示されました。

クラスメソッドの場合は、そのメソッドで使用している引数や戻り値のデータタイプを表示してくれました。

クラスリファレンスをいちいち開いて確認しなくても、エディタ上で確認ができて便利ですね。

0
0 156
記事 Mihoko Iijima · 2月 14, 2023 4m read

開発者の皆さん、こんにちは!

InterSystems デベロッパーツールコンテスト2023が開催され、21の応募作品の中から勝者が発表されました🏆

この記事では、世界のIRIS開発者の皆さんから注目を集めた作品をご紹介します。

最初は、Experts Nomination 第1位に輝いた @Dmitry Maslennikov さんの作品をご紹介します!

@Dmitry Maslennikov さんが解説されている記事(Welcome irissqlcli - advanced terminal for IRIS SQL)もあります。ぜひこちらもご覧ください。

@Dmitry Maslennikov さんは、IRIS SQL用の高度なターミナル irissqlcli を開発されました。

irissqlcli を使用すると、SQL記述時にSQL構文、関数、型、IRIS内テーブル名、カラム名に対する候補が表示されるため、SQL文がとても書きやすくなります。

ヘルプも充実しています。(\n でヘルプが表示されます)

接続先のテーブル一覧を取得する場合は「.tables」で取得できました。

また、以下のように記入時に入力候補が表示されます。Pygments を利用されているようで、シンタックスがハイライトされてきれいです。

0
0 193
お知らせ Mihoko Iijima · 2月 10, 2023

開発者の皆さん、こんにちは!

【InterSystems デベロッパーツールコンテスト】の投票が開始されました!

🔥 ベストアプリケーションはこれだ!! 🔥 と思う作品にぜひ投票をお願いします!

(今回は21作品がエントリーされています!)

投票方法は以下ご参照ください。

0
0 127
お知らせ Mihoko Iijima · 1月 30, 2023

開発者の皆さん、こんにちは!

InterSystems デベロッパーツールコンテスト 2023のテクノロジーボーナスが発表されました!

  • Embedded Python の利用
  • Docker コンテナの利用
  • ZPM パッケージを使ったデプロイ
  • オンラインデモの公開
  • Code Quality をパスする
  • コミュニティに記事を書く
  • コミュニティに2つ目の記事を書く
  • YouTubeにビデオを公開する
  • はじめてチャレンジされた方
  • InterSystems Idea 内 Community Opportunityの実装

獲得ポイントについて詳細は、以下ご参照ください。

Embedded Python の利用 - 3 points

あなたのアプリケーションで Embedded Python を使用している場合、3ポイント獲得できます。Embedded Pythonを使用するためには、IRIS 2021.2以降のバージョンをご利用ください。

 

Docker コンテナの利用 - 2 points

InterSysetms IRISが稼働している docker コンテナを使用している場合、Docker コンテナボーナスを獲得できます。

テンプレートはこちらにあります。

ご参考:開発環境テンプレート(IRIS プログラミングコンテストで使用していたテンプレート)の一覧

0
0 104
お知らせ Mihoko Iijima · 1月 15, 2023

開発者の皆さん、こんにちは!

2023年最初のコンテストの開催が決定しました!今回は、開発者の皆さんの開発が快適になるような便利ツールをご応募いただくコンテストです!

🏆 InterSystems デベロッパーツールコンテスト🏆

InterSystems IRISを使用して、開発のスピードアップ、より定性的なコードの貢献、テスト、デプロイ、サポート、ソリューションのモニタリングを支援するアプリケーションを提出してください。

期間: 2023年1月23日~2月12日

賞金: $13,500

 

0
0 145
記事 Toshihiko Minamoto · 12月 31, 2022 5m read

YASPEはYAPE(Yet Another pButtons Extractor)の後継機種です。YASPEは、メンテナンスと拡張を容易にするために、多くの内部変更を行い、一から書き直しました。

YASPEの機能は以下の通りです。

  • 「InterSystems Caché pButtons」 および 「InterSystems IRIS SystemPerformance」 ファイルを解析してグラフ化し、オペレーティング・システムおよび IRIS のメトリックを迅速にパフォーマンス解析します。
  • アドホックチャートを作成したり、「Pretty Performance」オプションでOperating SystemとIRISの指標を組み合わせたチャートを作成することで、より深く掘り下げることが可能です。
  • 「System Overview」 オプションを使用すると、システムの詳細や一般的な設定オプションについて SystemPerformance ファイルを検索する手間を省くことができます。

YASPEはPythonで書かれています。ソースコードはGitHubで公開されており、Dockerコンテナ用には以下で公開されています。


YASPEは、現在のOperating SystemとIRISのバージョンに重点を置いています。古いバージョンを実行してYASPEに問題がある場合、YAPEを介してパフォーマンスファイルを正常に実行するかどうかを確認することができます。問題がある場合は、遠慮なくGitHubを通じて私に連絡してください。


出力ファイル

オプションは以下の通りです:

  • mgstat と vmstat または windows perfmon の全カラムの HTML または PNG チャートと、フォルダへの出力。
  • iostatのチャート作成は、大きなディスクリストがある場合、時間がかかることがあるため、オプションとします。
  • Excelなどでさらに手作業で加工するためのCSVファイルなどです。

サンプルチャート

Pretty Performance

以下はカスタムチャートの例で、Glorefs (mgstat) とTotal CPUの使用率 (vmstat)です。

画像例1

下の画像は、指定した時間へのズームを含むデフォルト画像の1つです(デフォルトは13:00-14:00)。

画像例2

システム概要

yaspe は、システムの概要と基本的な設定のチェックを含みます (-s)

このチェックは、システムの詳細を探すために SystemPerformance ファイルを探し回る手間を省くためのものです。以下は overview.txt の例です。

サイト名称のSystem Summary

ホストネーム         : YOURHOST
インスタンス         : SHADOW
オペレーティングシステム : Linux
プラットフォーム         : N/A
CPUの数             : 24
プロセッサー  : Intel(R) Xeon(R) Gold 6248 CPU @ 2.50GHz
メモリ           : 126 GB
共有メモリ    : globals 71680 MB + routines 1023 MB + gmheap 1000 MB = 73,703 MB
バージョン          : Cache for UNIX (Red Hat Enterprise Linux for x86-64) 2018.1.4 (Build 505_1U) Thu May 28 2020 10:11:16 EDT
収集日   : プロファイル実行「24hours」は、2021年11月22日16時15分00秒に開始されました。

注意:
- エラー発生時のジャーナルフリーズは使用できません。ジャーナルIOエラーが発生した場合、この期間に発生したデータベースアクティビティは復元できません。
- swappinessのパラメータは10です。データベースの場合、Linuxカーネルがメモリページをディスクにスワップする積極性を調整するために、5を推奨します。
- Hugepagesが設定されていない。パフォーマンス、メモリ効率、および共有メモリのページアウトを防ぐために、巨大なページメモリ空間を使用します。HugePagesを共有メモリ量よりはるかに大きく指定することはお勧めしません。なぜなら、未使用のメモリが他のコンポーネントで使用できなくなるからです。
- dirty_background_ratioのパラメータは10 です。InterSystems では、このパラメータを 5 に設定することを推奨しています。この設定は、pdflush がダーティページの書き込みを開始する前に、ダーティページで埋められるアクティブなメモリの最大パーセンテージです。
- dirty_ratio のパラメータは 30 です。インターシステムズでは、このパラメータを 10 に設定することを推奨しています。この設定は、タイムスライス中にプロセスがより多くの書き込みを許可される代わりに、ダーティバッファを自ら書き込むように強制される前に、ダーティページで満たすことができる総メモリの最大割合を示します。これらの変更により、Linuxのpdflushデーモンは、ストレージに大量の更新が殺到する可能性のあるキューを作成するのではなく、より頻繁にダーティページを書き出すように強制されます。

お勧め:
- 上記の注意を見直し、修正してください。。
- HugePagesを設定し、IRISのドキュメントを参照してください: https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GCI_prepare_install#GCI_memory_big_linux
- 総メモリ量は128,755MB、総メモリ量の75%は96,566MBです。
- 共有メモリ(グローバル+ルーチン+gmheap)は73,703MBです。(総メモリの57%)です。
- ( 73,703 MB + 5% バッファ = 77,388 MB ) のページサイズ 2048 KB の HugePages 数は、38694 です。

このホストのすべてのインスタンスは:
- >SHADOW            2018.1.4.505.1.a  56772  /cachesys

0
0 104
記事 Toshihiko Minamoto · 10月 11, 2022 2m read

皆さん、こんにちは。 このプロジェクトをコンテストに応募します。 エクスポートモジュールは、多くのプロジェクトに不可欠であり、通常、本番サーバーにて使用されています。

属性初期化モジュールの呼び出しにて、さまざまなシナリオを実装しました。GCR で実証する多くの追加プロジェクトによる最大化と、本番インスタンスにネイティブにインストールするための最小化の両方です。

zpm "install appmsw-sql2xlsx -Dzpm.demo=none"

可能性をお見せするために、fileservercsvgen プロジェクトを使用しました。

可能性を実演するに当たって、次の手順を実行することを提案します。まず、デモを読み込み、superuser \ SYS を使ってユーザー名とパスワードを入力してください。表示されるウィンドウで、Search ボタン、そして Export をクリックします。

画像

次に、csvgen メニュー項目を選択します。

画像

表示されるタブで Load ボタンをクリックしたら、Search ボタン、そして Export をクリックします。

画像

次に、Fileserver メニュー項目を選択します。 画像

Download 可能な Excel ファイルのリストが表示されます。

画像

テンプレートから Excel ファイルが生成されます。

ぜひ、投票してください。

追伸 PR をまたマージしていない場合、変更したフォークをリポジトリから直接読み込むことが可能です。

0
0 223
記事 Toshihiko Minamoto · 1月 18, 2022 3m read

この短い記事では、マシンにPythonをセットアップしなくて済むように、dockerコンテナでYapeを実行する方法について説明します。

このシリーズの前回の記事からしばらく時間が経っているため、簡単に振り返ってみましょう。

まず、matplotlibで基本的なグラフを作成する方法について話しました。 そして、bokehを使った動的グラフについて紹介しました。 最後にパート3では、monlblデータを使ったヒートマップの生成について説明しました。

フィードバックをさまざまなチャンネルを通じて受け取りましたが、これらを実行するための環境をセットアップするのが困難であるという、共通したテーマが見られました。 そこで、それを少しでも簡単に行えるよう、Murrayと協力して、Murrayの優れたYapeツール用のDockerfileを作成してみることにしました。 GitHubページ

もちろん、これを行うには、マシンにdockerがインストールされている必要があります。

Dockerfile

公式のPythonイメージに基づく、どちらかと言えば単純なdocker定義:

FROM python:3

WORKDIR .

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

ソース

Requirements.txtには、Yapeを起動して実行するために必要なパッケージが含まれています。

altgraph==0.10.2
py-dateutil==2.2
bdist-mpkg==0.5.0
certifi==2017.7.27.1
cffi==1.10.0
chardet==3.0.4
idna==2.5
bokeh==0.12.6
macholib==1.5.1
matplotlib==2.0.2
pandas==0.20.3
modulegraph==0.10.4
numpy==1.13.1
py2app==0.7.3
pycparser==2.18
pyparsing==2.0.1
python-dateutil==1.5
pytz==2013.7
requests==2.18.3
six==1.4.1
urllib3==1.22
zope.interface==4.1.1

ソース

イメージをビルドするには、GitHubリポジトリを確認してから、docker buildを実行します。

git clone https://github.com/murrayo/yape.git
docker build -t yape .

プルリクエスト がマージされるまでは、https://github.com/kazamatzuri/yape.gitを使用してください)

使用しているマシンやインターネット接続の速度にもよりますが、これには数分かかります。

その後、以下のようにして、pButtonsファイルでYapeを実行できます。

docker run -v `pwd`/in:/data  --rm --name yape-test yape  \
./extract_pButtons.py -o /data \ 
/data/pButtons.html

docker run -v `pwd`/in:/data  --rm --name yape-test yape  \ 
./graph_pButtons.py -o /data/charts /data

現在の作業ディレクトリでは

    /in

を使用しているため、それをコンテナの/dataにマッピングします。 そこからpButtons.htmlを取得し、グラフをそのディレクトリに出力します。

注意事項

スクリプトにパラメーターを追加する必要がありました。公式のYapeリポジトリにマージしているところです(プルリクエスト

0
0 127
記事 Toshihiko Minamoto · 1月 11, 2022 3m read

これまでに何度もコードカバレッジとコードのパフォーマンス最適化について説明してきたため、ほとんどの方はすでにSYS.MONLBLユーティリティについてご存知かと思います。 コードを視覚的に見る方が通常は、純粋な数値を見るよりもはるかに直感的に理解できます。これが、このシリーズの記事の大きなポイントです。 今回は、Pythonとそのツールから少し離れて、^%SYS.MONLBLレポートからヒートマップを生成する方法を探りたいと思います。

簡単に言うと、ヒートマップは特定の値を色で表現してデータの要約を得ることに特化した視覚化ツールです。 このケースでは、データはコード行であり、コード行に掛けられた時間が色にマッピングされます。

^%SYS.MONLBL

行ごとに監視するモニターの実行については、ドキュメントをご覧ください。 つまり、分析の完全な出力をCSVファイルとして操作します。 分析しようとしているコードのソースコードが実際にあれば、はるかに便利であるため、 kフラグ(ソースを保持)を使ってコードをコンパイルするようにしてください。

出力の準備

ターゲット出力として、準備されたhtmlファイルを使用することにします。 これには、非常に基本的なレイアウトと、最終的な色付けを行うための小さなJavaScript関数だけが含まれます。

<!doctype html>
<html class="no-js" lang="">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
        <link rel="apple-touch-icon" href="apple-touch-icon.png">

        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.2.0/normalize.min.css">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
        <!--<link rel="stylesheet" href="css/main.css"> -->
            <style>

        table, th, td {
            width:"100%";
            border: 1px solid black;
            border-collapse: collapse;
        }
        pre {
            margin:1px;
        }
        th {
            text-align: left;
        }
    </style>

    <script>
    function rgba(r, g,b,a){
        r = Math.floor(r);
        g = Math.floor(g);
        b = Math.floor(b);
        return ["rgba(",r,",",g,",",b,",",a,")"].join("");
    }
    function colorize() {
        var rows=$("#data tr")
        var max=Math.max.apply(Math,rows.slice(1,rows.length).map(function(){ return this.childNodes[2].textContent}))
        for (i=1;i<rows.length;i++){
            var val=rows[i].childNodes[2].textContent;
            var c=(Math.pow(1-val/max,3))*255;
            var col=rgba(255,c,c,0.7);
            console.log(col);
            rows[i].style.backgroundColor=col;
        }
    }
    </script>
    </head>

    <body onload="colorize()">
        <!--[if lt IE 8]>
            <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->

        <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
        <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.12.4.min.js"><\/script>')</script>

<table id="data">
<tr><th>Routine</th><th>Line</th><th>Total Time</th><th>Code</th></tr>
<!--output-->
</table>


    </body>
</html>

解析してまとめる

生成されたCSVから関連する情報を取得してテンプレートに入れるには、以下のスクリプトを使用します。

monlbl.sh

#!/bin/bash

cat $1|grep -vi totals| awk -F"," 'FNR>1 {out="<tr><td>"$1"</td>" "<td>" $2 "</td><td>" $54 "</td><td><pre>"; for(i=55;i<=NF;i++){out=out$i","}; out=substr(out, 1, length(out)-1) "</pre></td></tr>"; print out }'

gen-heatmap.sh

#!/bin/bash
./monlbl.sh $1 > /tmp/temp.data
sed -e '/<!--output-->/r/tmp/temp.data' template.html

上記を以下のようにして呼び出します。

./gen-heatmap.sh /tmp/report.csv > heatmap.html

最終的な出力 ヒートマップ

調整可能な要素

テンプレートに含まれる色付けの関数をよく見ると、時間には線形マッピングを使用していないことがわかります。

    function colorize() {
        var rows=$("#data tr")
        var max=Math.max.apply(Math,rows.slice(1,rows.length).map(function(){ return this.childNodes[2].textContent}))
        for (i=1;i<rows.length;i++){
            var val=rows[i].childNodes[2].textContent;
            var c=(Math.pow(1-val/max,3))*255;
            var col=rgba(255,c,c,0.7);
            console.log(col);
            rows[i].style.backgroundColor=col;
        }
    }

私がテストした例では、この方が非常にうまく機能することがわかりましたが、その度合いは条件によって異なる可能性があります。 明らかに、指数を増やしてより赤に押し込むこともできますし、その逆も可能です。

コード

関連ファイルはすべてこちらにあります。

0
0 172
記事 Toshihiko Minamoto · 12月 21, 2021 7m read

先週のディスカッションでは、1つのファイルのデータ入力に基づく単純なグラフを作成しました。 ご存知のように、解析して相関付けるデータファイルが複数あることがあります。 そこで今週は、perfmonデータを追加して読み込み、それを同じグラフにプロットする方法について学習しましょう。 生成したグラフをレポートやWebページで使用する可能性があるため、生成したグラフのエクスポート方法についても説明します。

Windowsのperfmonデータを読み込む

標準のpButtonsレポートから抽出されたperfmonデータは、少し独特なデータ形式です。 一見すると、かなり単純なCSVファイルで、 最初の行には列のヘッダーがあり、それ以降の行にはデータポイントが含まれています。 ただし、ここでの目的のために、値エントリーを囲む引用符をどうにかする必要があります。 標準的なアプローチを使用してファイルをPythonに解析すると、文字列オブジェクトの列ができてしまい、うまくグラフ化できません。

perfmonfile="../vis-part2/perfmon.txt"
perfmon=pd.read_csv(perfmonfile,
                    header=0,
                    index_col=0,
                    converters={0: parse_datetime
                    })

パート1で使用したmgstatファイルとは異なり、ヘッダー名は最初の行にあります。 最初の列にインデックスを定義しようと思います(こうすれば、前回のようにデータフレームのインデックスを再作成しなくて済むためです)。 最後に、実際にDateTimeを表すように最初の列を解析する必要があります。 そうでない場合、文字列インデックスになってしまうためです。 これを行うために、perfmonの日付を解析するヘルパー関数を定義します。

def parse_datetime(x):
    dt = datetime.strptime(x, '%m/%d/%Y %H:%M:%S.%f')

    return dt

これを実行したら、DataFrameでperfmonデータが得られました。
~~~python
<class 'pandas.core.frame.DataFrame'>
Index: 2104 entries, 01/03/2017 00:01:19.781 to 01/03/2017 17:32:51.957
Columns: 105 entries, \\WEBSERVER\Memory\Available MBytes to \\WEBSERVER\System\Processor Queue Length
dtypes: float64(1), int64(11), object(93)
memory usage: 1.7+ MB

大半の列は現在オブジェクトであることに注意してください。 これらの列を使用可能な形式に変換するために、to_numeric関数を使用します。 applyを使用して各列にこの関数を呼び出すことも可能ですが、それではインデックスがまた台無しになってしまいます。 そこで、データにその関数を適用しながら直接データをプロットすることにします。

プロット

この実行では、全CPUの合計特権時間をプロットすることに関心があります。 残念ながら、列番号は一定でなく、CPUとドライブの数によって異なります。 そのため、それがどの列かを調べて知る必要があります。 私の例では、91です。

perfmon.columns[91]

'\\\\WEBSERVER\\Processor(_Total)\\% Privileged Time'

前回と同じアプローチを使用して、Glorefs、Rdratio、および新しいPriviledged Timeでグラフを作成します。

plt.figure(num=None, figsize=(16,5), dpi=80, facecolor='w', edgecolor='k')
host = host_subplot(111, axes_class=AA.Axes)
plt.subplots_adjust(right=0.75)

par1 = host.twinx()
par2 = host.twinx()
offset = 60
new_fixed_axis = par2.get_grid_helper().new_fixed_axis
par2.axis["right"] = new_fixed_axis(loc="right",axes=par2,offset=(offset, 0))
par2.axis["right"].toggle(all=True)

host.set_xlabel("time")
host.set_ylabel("Glorefs")

par1.set_ylabel("Rdratio")
par2.set_ylabel("Privileged Time")
ws=30
p1,=host.plot(data.Glorefs,label="Glorefs")
p2,=par1.plot(data.Rdratio,label="Rdratio")
p3,=par2.plot(pd.to_numeric(perfmon[perfmon.columns[91]],errors='coerce'),label="PTime")

host.legend()

host.axis["left"].label.set_color(p1.get_color())
par1.axis["right"].label.set_color(p2.get_color())
par2.axis["right"].label.set_color(p3.get_color())

plt.draw()
plt.show()

ここでto_numericを使用することができます。

p3,=par2.plot(pd.to_numeric(perfmon[perfmon.columns[91]],errors='coerce'),label="PTime")

グラフ

出力をリダイレクト

このノートブックは、データを一目で確認するのに非常に優れていますが、最終的には、スクリプトを非対話的に実行できるようにしたいため、グラフをイメージとして出力したいと思います。 スクリーンショットには、明らかに伴う手作業が多くなりすぎるため、puplot関数の*savefig()*を使用します。

*draw()show()の呼び出しをsavefig()*呼び出しに置き換えます。

#plt.draw()
#plt.show()
plt.savefig("ptime-out.png")

こうすると、現在の作業ディレクトリにpngが表示されます。

高度な出力

ちょっとした追加演習として、Bokehを見てみましょう。 Bokehがツールボックスに追加する多数の優れた機能の1つに、グラフをインタラクティブなHTMLファイルとして出力する機能があります。 インタラクティブとは、この場合、データをスクロールしてズームインできることを指します。 グラフ同士を関連付ける機能を追加すると、pButtonsデータ(またはその他のデータ)のインタラクティブなレンダリングを簡単に作成することができます。 これらは、あらゆる最新のブラウザで実行し、多数の人に簡単に配布できるため、特に便利です。

今のところは、2 つのグラフを出力に追加することを狙いとしています。 perfmonのGlorefsと特権時間を1つのページにまとめたいと思います。

そのためにはまず、Bokehをインポートする必要があります。

from bokeh.plotting import *

いくつかのプロパティとラベルを定義し、各プロットのサイズも決定します。 その後で、先に収集していたデータオブジェクトをプロットすれば、それで完了です。

コメントアウトされている*output_notebook()*は、Jupyterノートブックに直接出力をレンダリングすることに注意してください。 最終的にファイルを配布できるようにするため、output_fileを使用しています。

output_file("mgstat.html")
#output_notebook()
TOOLS="pan,box_zoom,reset,save"

left = figure(tools=TOOLS,x_axis_type='datetime',
    title="Glorefs",width=600, height=350,
   x_axis_label='time'
)
right=figure(tools=TOOLS,x_axis_type='datetime',
    title="PTime",width=600, height=350,
   x_axis_label='time',x_range=left.x_range
)
left.line(data.index,data.Glorefs,legend="Glorefs",line_width=1)
right.line(perfmon.index,pd.to_numeric(perfmon[perfmon.columns[91]],errors='coerce'),legend="privileged time",line_width=1)
p=gridplot([[left,right]])
show(p)

ここで重要なのは、2つのグラフの範囲の関連付けをx_range=left.x_rangeで行っているところです。 これにより、右側のウィンドウは左側のウィンドウでの選択/ズーム/移動によって(またはその逆で)更新されます。

TOOLSリストは、結果表示に含めたいツールのリストに過ぎません。 gridplotを使用することで、2つのグラフを隣り合わせに配置しています。

mgstat-bokeh

また、GitHubリポジトリでも、結果のHTMLを確認することができます。 GitHubから直接配信するには大きすぎるようなので、ダウンロードする必要があります。

まとめ

このセッションでは、さまざまなソースからデータを取得し、同じグラフにレンダリングする方法を探りました。 また、サンプリング頻度の異なるデータも扱っています(気づかなかったでしょう(^_-) )。 Bokehを使うと、グラフを配布可能なインタラクティブビューで簡単に作成できる強力なツールを得られます。 次のいくつかのセッションでは、csp.log、apache/iis アクセスログ、cconsole.logイベントなど、さらにプロットについて探りたいと思います。 Pythonで処理してほしいデータについて何か提案があれば、遠慮なくコメントに残してください。

あなたの体験をシェアしてください! これは読者との対話で成り立つ学習過程を意図したブログです!

リンク

この記事で使用したすべてのファイルは、こちらにあります。 また、ここで説明された一部のテクニックに基づく@murrayoの新しいeButtons抽出ツールもぜひご覧ください。 https://github.com/murrayo/yape

0
0 182
記事 Toshihiko Minamoto · 9月 23, 2021 10m read

この記事は、視覚化ツールと時系列データの分析を説明する連載の最初の記事です。 当然ながら、Caché製品ファミリーから収集できるパフォーマンス関連のデータを見ることに焦点を当てますが、 説明の途中で、他の内容についても解説していきます。 まずは、Pythonとそのエコシステムで提供されているライブラリ/ツールを探りましょう。

この連載は、Murrayが投稿したCachéのパフォーマンスと監視に関する優れた連載(こちらから参照)、より具体的にはこちらの記事と密接に関係しています。

免責事項1: 確認しているデータの解釈について話すつもりですが、それを詳しく話すと実際の目標から外れてしまう可能性があります。 そのため、Murrayの連載を先に読んで、主題の基本的な理解を得ておくことを強くお勧めします。

免責事項2: 収集したデータを視覚化するために使用できるツールは山ほどあります。 その多くは、mgstatなどから得たデータを直接処理するが、必要最低限の調整だけで処理することができます。 この記事は「このソリューションがベストですよ」という投稿ではまったくなく、 あくまでも、「データを操作する上で便利で効果的な方法を見つけたよ」という記事です。

免責事項3: データの視覚化と分析は、詳しく見るほど非常にやみつきになる、刺激的で楽しい分野です。 これに没頭して自由な時間を失ってしまう可能性があります。 でも、警告しましたからね!

では、前置きはこれくらいにして、早速内容を見ていきましょう。

前提条件

始める前に、次のツールとライブラリを用意してください。

  • Jupyterノートブック
  • Python (3)
  • 作業中に使用するさまざまなPythonライブラリ

Python(3): マシンに Python が必要です。 アーキテクチャごとにインストールの方法が様々です。 私はmacでhomebrewを使用しており、これを使って簡単にインストールできました。

brew install python3

Googleであなたのお気に入りのプラットフォームに使用できる手順を検索してください。

Jupyterノートブック: 厳密には必要ではありませんが、Jupyterノートブックがあれば、Pythonスクリプトでの作業が楽になります。 ブラウザウィンドウからインタラクティブにPythonスクリプトを実行して表示することができます。 また、スクリプトでの共同作業も可能です。 コードの実験と操作を非常に簡単に行えるようになるため、強くお勧めします。

pip3 install jupyter

(繰り返しになりますが、$search(検索)エンジンに尋ねてください)

Pythonライブラリ Pythonライブラリについては使用しながら説明します。 importステートメントでエラーが発生している場合は、まずは、ライブラリがインストールされていることを確認してください。

pip3 install matplotlib

はじめに

マシンにすべてがインストールされていれば、ライブラリから

jupyter notebook

を実行できるはずです。 このコードを実行すると自動的にブラウザウィンドウが開き、単純なUIが表示されます。 空のノートブック

早速メニューから新しいノートブックを作成し、最初のコードセルにインポートステートメントをいくつか追加します(新規 -> ノートブック -> Python3)。

ノートブックのインポート

import math
import pandas as pd
import mpl_toolkits.axisartist as AA
from mpl_toolkits.axes_grid1 import host_subplot
import matplotlib.pyplot as plt
from datetime import datetime
from matplotlib.dates import DateFormatter

インポートしているライブラリについて、いくつかのコメントがあります。

  • Pandas これは、Pythonプログラミング言語向けの高性能で使いやすいデータ構造とデータ解析ツールを提供するオープンソースのBSDラインセンスライブラリです。 これにより、ビッグデータセットを効率的に処理することができます。 pButtonsから取得するデータセットは、決して「ビッグデータ」ではありませんが、 一度にたくさんのデータを確認できるので安心です。 過去20年に渡って、24時間/2秒サンプリングでpButtonsを収集していたとしても、 それをグラフ化できるということです。
  • Matplotlib mataplotlibは、さまざまなハードコピー形式やプラットフォーム間でのインタラクティブ環境で出版グレードの図を生成するPythonの2Dグラフ作成ライブラリです。 この記事のメインのグラフ作成エンジンとしてとりあえず使用するのがこのライブラリです。

現在のコードセルの実行(ショートカット: Ctrl+Enter)(ショートカット一覧)でエラーが発生している場合は、上記のライブラリがインストールされていることを確認してください。

また、Untitledノートブックの名前も変更していることに気づくでしょう。名前を変更するには、タイトルをクリックしてください。

データの読み込み

基礎工事が終了したので、データをいくらか読み込むことにしましょう。 幸い、PandasにはCSVデータを簡単に読み込む方法があります。 都合よくcsv形式のmgstatデータのセットが手元にあるため、それを使うことにします。

mgstatfile = '/Users/kazamatzuri/work/proj/vis-articles/part1/mgstat.txt'
data = pd.read_csv(
    mgstatfile, 
    header=1,
    parse_dates=[[0,1]]
   )

read_csvコマンドを使用して、mgstatデータを直接DataFrameに読み取っています。 オプションに関する総合的な概要は、ドキュメント全文をご覧ください。 つまり、読み取るファイルを渡して、2行目(1行目は0です!)にヘッダー名が含まれていることを伝えているだけです。 mgstatは日付と時刻のフィールドを2つのフィールドに分割するため、parse_datesパラメーターでそれらのフィールドを組み合わせることも必要です。

data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 25635 entries, 0 to 25634
Data columns (total 37 columns):
Date_       Time        25635 non-null datetime64[ns]
  Glorefs               25635 non-null int64
 RemGrefs               25635 non-null int64
 GRratio                25635 non-null int64
  PhyRds                25635 non-null int64
 Rdratio                25635 non-null float64
 Gloupds                25635 non-null int64
 RemGupds               25635 non-null int64
 Rourefs                25635 non-null int64
 RemRrefs               25635 non-null int64
  RouLaS                25635 non-null int64
 RemRLaS                25635 non-null int64
  PhyWrs                25635 non-null int64
   WDQsz                25635 non-null int64
  WDtmpq                25635 non-null int64
 WDphase                25635 non-null int64
  WIJwri                25635 non-null int64
  RouCMs                25635 non-null int64
 Jrnwrts                25635 non-null int64
   GblSz                25635 non-null int64
 pGblNsz                25635 non-null int64
 pGblAsz                25635 non-null float64
   ObjSz                25635 non-null int64
 pObjNsz                25635 non-null int64
 pObjAsz                25635 non-null int64
   BDBSz                25635 non-null int64
 pBDBNsz                25635 non-null int64
 pBDBAsz                25635 non-null float64
  ActECP                25635 non-null int64
  Addblk                25635 non-null int64
 PrgBufL                25635 non-null int64
 PrgSrvR                25635 non-null int64
  BytSnt                25635 non-null int64
  BytRcd                25635 non-null int64
  WDpass                25635 non-null int64
  IJUcnt                25635 non-null int64
 IJULock                25635 non-null int64
dtypes: datetime64[ns](1), float64(3), int64(33)
memory usage: 7.2 MB

上記は、収集されたDataFrameの概要を示します。

データの操作

一部のフィールド名にはスペースが含まれており、「Date_ Time」は扱いにくいため、文字列を削除して最初の列の名前を変更します。

data.columns=data.columns.str.strip()
data=data.rename(columns={'Date_       Time':'DateTime'})

DataFrameはデフォルトでRangeIndexになります。 これはこのデータを確認するにはあまり役に立ちません。 より実用的なDateTime列を使用できるため、それをインデックスとして設定することにします。

data.index=data.DateTime

これで、最初のバージョンのプロットを作成できるようになりました。 最初に確認するものの1つは必ずGlorefsであるため、Glorefsを使用してみましょう。

plt.figure(num=None, figsize=(16,5), dpi=80, facecolor='w', edgecolor='k')
plt.xticks(rotation=70)
plt.plot(data.DateTime,data.Glorefs)
plt.show()

まず、ライブラリにグラフのサイズを指示しています。 また、x軸のラベルを少し回転させて、重なり合わないようにしています。 最後に、DateTimeとGlorefsのプロットを作成し、グラフを表示しています。 これで、次のようなグラフが出来上がります。

Glorefs

Glorefsをほかの列に置き換えるだけで、何が起きているのかを大まかに捉えることができます。

グラフの合成

複数のグラフをまとめて表示すると非常に便利な場合があります。 そのため、当然、複数のプロットを1つのグラフに描こうと考えるでしょう。 matplotlib だけでこれを行うのは非常に簡単です。

plt.plot(data.DateTime,data.Glorefs)
plt.plot(data.DateTime,data.PhyRds)
plt.show()

ところが、これでは前とほぼ同じグラフが作成されてしまいます。 問題はy軸です。 Glorefsは数百万に達するのに対し、PhyRdsはたいてい数百(から数千)であるため、PhyRdsはほぼ読み取れません。

これを解決するには、前にインポートしたaxisartistツールキットを使用する必要があります。

plt.gcf()
plt.figure(num=None, figsize=(16,5), dpi=80, facecolor='w', edgecolor='k')
host = host_subplot(111, axes_class=AA.Axes)
plt.subplots_adjust(right=0.75)

par1 = host.twinx()
par2 = host.twinx()
offset = 60
new_fixed_axis = par2.get_grid_helper().new_fixed_axis
par2.axis["right"] = new_fixed_axis(loc="right",axes=par2,offset=(offset, 0))
par2.axis["right"].toggle(all=True)

host.set_xlabel("time")
host.set_ylabel("Glorefs")
par1.set_ylabel("Rdratio")
par2.set_ylabel("PhyRds")

p1,=host.plot(data.Glorefs,label="Glorefs")
p2,=par1.plot(data.Rdratio,label="Rdratio")
p3,=par2.plot(data.PhyRds,label="PhyRds")

host.legend()

host.axis["left"].label.set_color(p1.get_color())
par1.axis["right"].label.set_color(p2.get_color())
par2.axis["right"].label.set_color(p3.get_color())

plt.draw()
plt.show()

簡単に要約すると、2つのy軸をプロットに追加し、それぞれに異なる尺度を設定するということになります。 最初の例では暗黙的にサブプロットを使用しましたが、この場合は、直接それにアクセスして、軸とラベルを追加する必要があるため、 2つのラベルと色を設定しています。 凡例を追加して、様々なプロットに色を繋げたら、次のような画像になります。

合成

最後に

これでデータをプロットするための非常に強力なツールを手に入れました。 mgstatデータを読み込んでいくつかの基本的なプロットを作成する方法を探りました。 次のパートでは、ほかのグラフの出力形式を試し、さらに多くのデータを取得することにします。

コメントやご質問をお受け付けしております! あなたの体験をシェアしてください!

-Fab

追伸: これに使用するノートブックはこちらにあります。

0
0 155
お知らせ Shintaro Kaminaka · 7月 8, 2021

開発者の皆さん、こんにちは!

HL7v2メッセージをFHIR(Fast Healthcare Interoperability Resources)に変換するニーズがあり、その変換プロセスが複雑で分かりにくいと感じたことはありませんか?インターシステムズは、HL7v2メッセージをFHIR(Fast Healthcare Interoperability Resources)に変換するプロセスを簡単にする、HealthShareメッセージ変換サービス(HealthShare Message Transformation Services)と呼ばれる新しいクラウドベースのSaaSサービスを展開しています。 この新しいサービスの早期アクセス・プレビュー・プログラムを発表できることを嬉しく思います。 必要なのは、無料のAWSアカウントと、HL7v2メッセージをドロップするためのS3バケット、そしてFHIR出力を得るための別のS3バケットだけです。

この機能の簡単なデモをご覧ください。

<iframe allow="encrypted-media" allowfullscreen="" frameborder="0" gesture="media" height="315" scrolling="no" src="https://www.youtube.com/embed/Js0SDUZbXv8" width="560"></iframe>

インターシステムズ社のラーニングサイトでは、AWS の無料アカウントとインターシステムズ社のクラウド・ポータルの無料アカウントにサインアップして、変換サービスの強力な機能を利用するための簡単なステップ・バイ・ステップ・ガイドを提供しています。 完全なドキュメントは、インターシステムズ社のドキュメントでご覧いただけます。

このサービスは、7月下旬に正式に開始される予定です。プレビューが終了しても、最初の100万件の変換を無料で利用することができます。

インターシステムズ社のこの新しいオファーの詳細は以下の内容です:

HealthShareメッセージ変換サービスの紹介。

医療IT業界では、FHIR® (Fast Healthcare Interoperability Resources)が、ヘルスケアデータを交換するための最新のデータ標準として採用されています。 オンデマンドのHealthShareメッセージ変換サービスを利用することで、医療機関、保険会社、製薬会社は、既存のデータフォーマットをFHIR規格に変換し、データから最大限の価値を引き出すことができます。 インターシステムズは、最新のFHIR規格だけでなく、HL7v2、X12、CDA、C-CDA、DICOMを含むすべての主要なヘルスケア規格を実装しており、ヘルスケアの相互運用性におけるリーダー的存在です。

HealthShareメッセージ変換サービスは、これらの以前の標準からFHIR R4へのメッセージ変換を簡単に行えるように設計されており、初期リリースではHL7 v2メッセージのFHIR R4への変換をサポートしています。 FHIRメッセージは、AWS S3バケットまたはAmazon HealthLake (Preview)に送ることができ、将来的には他のFHIRリポジトリオプションも追加される予定です。

HealthShareメッセージ変換サービスは、HL7v2メッセージをFHIRに変換することを簡単にします。 変換ロジックを気にする必要がないので、メッセージ変換の複雑な作業はインターシステムズに任せて、優れたヘルスケア・アプリケーションの構築に集中することができます。このサービスが提供するのは

  • AWS上での簡単なプロビジョニングと起動
  • インバウンドS3バケットのHL7v2メッセージのチェック
  • HL7コンテンツのバリデーション
  • FHIR R4へのメッセージ変換
  • 変換されたメッセージを、アウトバウンドの S3 バケット、InterSystems FHIR Accelerator (Preview) サービス、または Amazon HealthLake (Preview) リポジトリにルーティングする
  • 変換パイプラインのステータスと統計情報のモニタリング

さらに、このサービスはAWSのインフラ上に構築されているため、ISO 27001:2013およびHIPAAをサポートするHITRUST認証を取得しています。インターシステムズは、このサービスの運用、監視、バックアップを管理しています。

そして何より、このサービスが商業的に開始されると、最初の100万回の変換が無料で提供され、その後は使用した分だけを支払うことになり、変換されたメッセージあたりのコストは非常に低く抑えられます。 このサービスを利用するための長期契約はなく、いつでも解約できます。

皆様からのフィードバックをお待ちしております。 この記事のコメント欄にご意見をお寄せいただくか、 HMTS@InterSystems.com まで直接お問い合わせください。

HL7 ® と FHIR ® は Health Level Seven International の登録商標であり、これらの商標の使用は HL7 による推奨を意味するものではありません。FHIR商標の使用は、HL7によるHealthShare Message Transformation ServicesまたはHealthShare Message Transformation Servicesの推奨を意味するものではありません。

0
0 508
記事 Tomoko Furuzono · 6月 29, 2021 3m read

これは、InterSystems FAQサイトの記事です。
 

IRISのターミナルスクリプトを使用することで、コマンドラインからの入力作業なしで IRIS のユーティリティを実行することが可能になります。

また、IRISのルーチンやクラスを、Windows のバッチファイルで実行する場合(irisコマンドで実行)は、「認証なし」もしくは「オペレーティングシステム認証」を指定していただく必要がありますが、パスワード認証のみしか使用できないような場合に、ターミナルスクリプトを使用する方法が使えます。 手順は、以下のようになります。

--------------------------------------------------------------------------------------------
iristerm.exeを使用します。
これはプロンプトが返ってきてユーザが入力を必要とするもの(例えば^%GSIZEなど)にも有効です。
詳細は以下をご覧ください。import.scrの中身を変更することであらゆるIRISのユーティリティの実行に使用できます。

1. トピック下部にあるサンプル import.scr を、適当なディレクトリに配置して下さい。
(ここではC:\import.scr とします)

2. 以下のように実行します。 

0
0 871
記事 Megumi Kakechi · 4月 9, 2021 2m read

これは InterSystems FAQ サイトの記事です。
 

グローバル変数毎のデータベースキャッシュ使用量を確認するツール(^GLOBUFFユーティリティ)が用意されています。

%SYSネームスペースにて、ユーティリティを直接実行する方法と、プログラムで実行する方法があります。
 

ユーティリティを直接実行する方法は以下のようになります。

0
0 437
記事 Megumi Kakechi · 3月 2, 2021 2m read

これは InterSystems FAQ サイトの記事です。


管理ポータル:システムオペレーション > データベース にあるオプションボタンラジオボタン)「空き容量ビュー」で表示される内容は、システムクラス SYS.Database のFreeSpace クエリで取得可能です。

    

次のようなコードでクエリを実行します。

例:
(%SYSネームスペースにて作成、実行します)

 /// ZISJ.mac
 Set stmt=##class(%SQL.Statement).%New()
 Set status=stmt.%PrepareClassQuery("SYS.Database","FreeSpace")
 Set rs=stmt.%Execute()
 While rs.%Next() {
   Write !
   For i=1:1:9 {
     Write rs.%GetData(i),","
   }
 } 


もしくは、以下のようにも行えます。

0
0 373
記事 Mihoko Iijima · 2月 25, 2021 2m read

これは InterSystems FAQ サイトの記事です

復旧を優先される場合を除き 【トラブル発生状態のまま】弊社サポートセンターまでご連絡ください。

その際、専用ツールを利用して情報収集いただくことで(所要時間約 5分)、サポートセンターによる状況確認がスムーズに行えます。

ツール使用方法については、PDF または以下ビデオでご紹介しています。

※ InterSystems IRIS / IRIS for Health をご利用の方は、こちらの記事をご参照ください。

ぜひ 1 度、テスト/開発環境で実行をお試しいただき、万が一の場合に備えていただければ思います。

ビデオの目次(YouTubeでもご覧いただけます)

0:00~1:40 情報収集ツールを使用する上での大事なポイント

1:41~2:15 ツールの種類について

2:15~3:45 どのツールを実行したらいいか困った時の考え方

3:45~5:04 管理ポータルの診断レポートの例

5:04~6:00 ^Buttonsの実行例(Cache)

6:00~7:12 ^Buttonsの実行例(Ensemble / Cacheベースの HealthConnect)

7:12~8:27 CacheHungスクリプトの実行例(Windowsの例)

8:27~9:30 CacheHungスクリプトの実行例(Linuxの例)

0
0 206
記事 Mihoko Iijima · 2月 25, 2021 1m read

これは InterSystems FAQ サイトの記事です。

復旧を優先される場合を除き 【トラブル発生状態のまま】弊社サポートセンターまでご連絡ください。

その際、専用ツールを利用して情報収集いただくことで(所要時間約 5分)、サポートセンターによる状況確認がスムーズに行えます。

ツール使用方法については、PDF または以下ビデオでご紹介しています。

※ Caché/Ensemble/Caché ベースの HealthConnect をご利用の方は、こちらの記事をご参照ください。

ぜひ 1 度、テスト/開発環境で実行をお試しいただき、万が一の場合に備えていただければ思います。

ビデオの目次(YouTubeでもご覧いただけます)

0:00~1:40 情報収集ツールを使用する上での大事なポイント

1:41~2:24 ツールの種類について

2:24~3:45 どのツールを実行したらいいか困った時の考え方

3:45~5:04 管理ポータルの診断レポートの例

5:04~6:30 ^SystemCheckの実行例

6:30~7:50 IRISHungスクリプトの実行例(Linuxの例)

7:50~8:50 IRISHungスクリプトの実行例(Windowsの例)

8:50~9:52 ツールから生成されたHTMLのファイル名について

9:52~11:32 ツールから生成されたHTMLの中身について

11:32~ まとめ

0
0 353
記事 Toshihiko Minamoto · 10月 14, 2020 9m read


こんにちは!

この記事では、IRIS から Caché、Ensemble、HealthShare など、InterSystems の製品で使用されるクラスやその構造を理解するのに役立つツールの概要を簡単にまとめています。

つまり、そのツールはクラスやパッケージ全体を視覚化し、クラス間の相対関係を示し、ディベロッパーやチームリーダーに必要な情報をすべて提供してくれるので、わざわざ Studio に移動してコードを調べる必要が省けます。

InterSystems の製品について情報を集めている方からたくさんのプロジェクトをレビューしている方、または単純に InterSystems Technology ソリューションの新機能に興味がある方まで、ObjectScript Class Explorer の概要をぜひお読みください!

InterSystems 製品のご紹介

以前は Caché として知られた IRIS はマルチレベルの DBMS です。 SQL クエリを使ってアクセスしたり、さまざまなプログラミング言語のインターフェースを使い、保管されているオブジェクトやプロシージャを操作したりできます。 ですが、DBMS に組み込まれているネイティブ言語の ObjectScript (COS) を使ってアプリケーションを開発することが、常に最初の選択肢として選ばれます。

Caché は DBMS レベルのクラスに対応しています。 クラスには主に、Persistent(データベースに保管できる) と Registered(データベースに保管されないが、プログラムやハンドラーとしての役割を果たす)の2 種類があります。 また、Serial(アドレスなどの複雑なデータ型を作成するために Persistent クラスに統合して使えるクラス) 、DataType(ユーザー定義のデータ型を作成する際に使用される) 、Index、View、Stream などの特殊なタイプもいくつかあります。

Class Explorer の概要

Caché Class Explorer は、Caché クラスの構造をダイアグラムとして視覚化し、クラスやすべての関連情報 (メソッドのコード、クエリ、xData ブロック、コメント、ドキュメンテーション、さまざまなクラス要素のキーワードなど) の依存関係を示すツールです。

機能

Caché にはクエリ、xData ブロック、メソッドやプロパティの多数のキーワード (System、ZenMethod、Hidden、ProcedureBlock など)、親子関係、一対多関係、クラス型といった、スタンダードな UML ではサポートされていないが、Caché には重要な一連のエンティティが存在するため、Class Explorer は拡張バージョンの UML 表記を使って視覚化を実行します。

Caché Class Explorer (バージョン1.14.3) では、次のことができます。

  • パッケージの階層、クラスのダイアグラム、パッケージ全体を表示する。
  • 表示されたダイアグラムの外観を編集する。
  • クラスのダイアグラムのその時点でのイメージを保存する。
  • ダイアグラムのその時点での外観を保存し、後で復元する。
  • ダイアグラムやクラスツリーに表示されるキーワードを使って検索を行う。
  • ツールヒントを使ってクラス、そのプロパティ、メソッド、パラメーター、クエリ、xData ブロックの完全な情報を確認する。
  • メソッドのコード、クエリ、または xData ブロックを表示する。
  • グラフィックアイコンを含むダイアグラム要素の表示を有効または無効にする。

この記事の残りの内容をよく理解していただけるよう、Class Explorer で視覚化されたクラスを見てみましょう。 それでは、例の 1 つとして、「SAMPLES」ネームスペースの「Cinema」パッケージを表示してみましょう。

詳細および機能の概要 

左側のサイドバーにパッケージツリーがあります。 パッケージ名にカーソルを合わせると、その右側にボタンが表示されるので、それをクリックしてパッケージ全体を表示します。 パッケージツリーの中からクラスを選択し、リンクされているクラスと一緒にレンダリングします。

Class Explorer で表示できるクラス間の依存関係には種類がいくつかあります。

  1. 継承。 継承先クラスを指す白い矢印で示されます。
  2. アソシエーションまたはクラス同士の関係。クラスのフィールドに別クラスのタイプが含まれている場合、ダイアグラムビルダーはこれをアソシエーション関係として示します。
  3. 親子関係と 一対多関係。データの整合性を維持するためのルール。

各関係にカーソルを合わせると、その関係を生み出すプロパティが強調表示されます。

Class Explorer は現在のパッケージの外に存在するクラス間の依存関係までは表示しません。 表示されるのは現在のパッケージ内のクラスのみです。また、Class Explorer によるクラス検索に制限を設定する場合は、「依存関係レベル」設定を使います。

クラスは長方形として表示され、以下の 6 つのセクションに分割されます。

  1. クラス名:クラス名にカーソルを合わせると、作成日、変更日、コメント、クラスに割り当てられたすべてのキーワードが表示されます。 クラスヘッダーをダブルクリックすると、そのドキュメンテーションが表示されます。
  2. クラスパラメーター: すべての割り当てられたパラメーターがタイプ、キーワード、コメントと共に表示されます。 斜体で表記されるパラメーターやすべてのプロパティは、カーソルを合わせるとツールヒントが表示されます。
  3. クラスプロパティ:クラスプロパティはパラメーターに似ています。
  4. メソッド:メソッドをクリックすれば、ソースコードが表示されます。 COS 構文は強調表示されます。
  5. クエリ:メソッドと同様に、クリックすればソースコードが表示されます。
  6. xData ブロック: 主に XML データで構成されるブロック クリックすると、フォーマットされたソースコードがブロックとして表示されます。

デフォルトで、各クラスは多数のグラフィックアイコンと一緒に表示されます。 各アイコンの意味は、画面の右上隅にある「ヘルプ」ボタンをクリックすれば分かります。 多少厳密な UML 表記をデフォルトで表示する必要がある場合や、クラスセクションを表示する場合は、グラフィックアイコンを設定セクションで無効にすることができます。

非常に大きなダイアグラムを使い慣れていない場合は、ダイアグラムのクイック検索機能を使うことができます。 入力したキーワードの一部を含むクラスが強調表示されます。 次のマッチにジャンプするには、Enter キーを押すか、検索ボタンをもう一度クリックします。

最後に、ダイアグラムの編集をすべて完了し、不要な関係をすべて削除し、各要素をそれぞれの適切な位置に配置して、希望通りの外観が出来上がれば、左下隅にある「ダウンロード」ボタンをクリックして保存します。

ピンボタン をアクティブにすると、クラス (またはパッケージ) の現在のセットのダイアグラムに配置されている要素の位置が保存されます。 例えば、クラス A と B を選択し、そのビューをピンボタンで保存すると、ブラウザーやマシンを再起動した後でも、クラス A と B を選択すれば完全に同じビューが表示されます。 しかし、クラス A だけを選択した場合は、デフォルトのレイアウトで表示されます。

インストール

Caché Class Explorer をインストールするには、最新リリース版 の XML パッケージだけをお好きなネームスペースにインポートしてください。 インポートが完了すると、「hostname / ClassExplorer /」という名前の新しい Web アプリ (最後のスラッシュは必須です) が表示されます。

インストールの詳しい手順

  1. Caché Class Explorer の最新リリースを含むアーカイブをダウンロードします。
  2. 「Cache/CacheClassExplorer-vX.X.X.xml」という名前の XML ファイルを抽出します。
  3. 以下のいずれかの方法でパッケージをお好きなネームスペースにインポートします。
    1. XML ファイルを Studio にドラッグする。
    2. System Management Portal を使用する場合: System Explorer -> Classes -> Import と順に移動し、ローカルファイルへのパスを指定する。
    3. ターミナルコマンドを使用する場合: do ##class(%Installer.Installer).InstallFromCommandLine(“Path/Installer.cls.xml”);
  4. インポートログを読み、問題がなければ「http://hostname/ClassExplorer/」から Web アプリケーションを開くことができます。 問題が発生した場合は、以下を確認してください。
    1. このネームスペースにクラスをインポートする権限があるか。
    2. Web アプリケーションのユーザーは異なるネームスペースへのアクセス権を持っているか。
    3. エラー 404 が表示される場合は、URL の最後に「/」を追加しているか。

他のスクリーンショット

[スクリーンショット 1] DSVRDemo パッケージ。クラス名にカーソルを合わせた状態。

[スクリーンショット 2] DataMining パッケージ。ダイアグラムでキーワード「TreeInput」を検索中。

[スクリーンショット 3] JavaDemo.JavaListSample クラスのメソッドコードを表示したビュー。

[スクリーンショット 4] ClassExplorer.Router クラスの XData ブロックのコンテンツを表示中。

Class Explorer の機能を標準の SAMPLES ネームスペース デモでお試しください。 プロジェクトのビデオレビューは こちら からご覧ください。

フィードバックやご提案、コメントはこちら、もしくは GitHub リポジトリからお寄せください。 どうぞお楽しみください!

0
0 395
記事 Shintaro Kaminaka · 7月 30, 2020 11m read

この記事では、RESTFormsプロジェクト(モダンなWebアプリケーション用の汎用REST APIバックエンド)を紹介します。

プロジェクトの背後にあるアイデアは単純です。私はいくつかのREST APIを書いた後、REST APIが一般的に次の2つの部分で構成されていることに気付きました。

  • 永続クラスの操作
  • カスタムビジネスロジック

また、独自のカスタムビジネスロジックを書く必要はありますが、RESTFormsには永続クラスの操作に関連するすべての機能を提供しています。

使用例

  • Cachéにすでにデータモデルがあり、REST API形式で情報の一部(またはすべて)を公開したい
  • 新しいCachéアプリケーションを開発しており、REST APIを提供したい

クライアントサイド

このプロジェクトはWebアプリケーションのバックエンドとして開発されているため、JSだけで事足ります。 形式の変換は必要ありません。

補足:CRUD

オブジェクトまたはコレクションに対し、次の4つの操作を実行できます。

  • Create(作成)
  • Read(読み込み)
  • Update(更新)
  • Delete(削除)

機能

RESTFormsを使用して以下を実行できます。

  • 公開されたクラスに対するCRUD - クラスのメタデータを取得し、クラスのプロパティを作成 / 更新 / 削除できます。
  • オブジェクトに対するCRUD - オブジェクトを取得 / 作成 / 更新 / 削除できます。
  • オブジェクトコレクションに対するRead(SQL経由) - SQLインジェクションから保護します。
  • 自己検出 – 最初に使用可能なクラスのリストを取得し、その後でクラスのメタデータを取得し、そのメタデータを基にしてオブジェクトに対するCRUDを実行できます。

パス

以下の表には、主なパスとRESTFormsを使用して実行できる操作を掲載しています。

<td>
  説明
</td>
<td>
  利用可能なすべてのクラスを一覧表示します
</td>
<td>
  すべてのクラスのメタデータを取得します
</td>
<td>
  クラスのメタデータ
</td>
<td>
  プロパティをクラスに追加します
</td>
<td>
  クラスのプロパティを変更します
</td>
<td>
  クラスのプロパティを削除します
</td>
<td>
  オブジェクトを取得します
</td>
<td>
  オブジェクトの1つのプロパティを取得します
</td>
<td>
  オブジェクトを作成します
</td>
<td>
  動的オブジェクトからオブジェクトを更新します
</td>
<td>
  オブジェクトからオブジェクトを更新します
</td>
<td>
  オブジェクトを削除します
</td>
<td>
  (SQL)クエリでクラスのオブジェクトを取得します
</td>
<td>
  (SQL)カスタムクエリでクラスのオブジェクトを取得します
</td>
URL
info
info/all
info/:class
field/:class
field/:class
field/:class/:property
object/:class/:id
object/:class/:id/:property
object/:class
object/:class/:id
object/:class
object/:class/:id
objects/:class/:query
objects/:class/custom/:query

**RESTFormsを使い始めるには?**
  1. GitHubからプロジェクトをインポートします(お勧めの方法は独自リポジトリにサブモジュールとして追加する方法ですが、単にリリースをダウンロードしても良いです)。
  2. RESTFormsを介して公開したい各クラスについて以下を実施します。
  • アダプタクラスから継承する
  • 権限を指定します(一部のクラスを読み取り専用として公開する場合などに実施)。
  • オブジェクトの表示値として使用されるプロパティを指定します。
  • 表示したいプロパティの表示名を指定します。

セットアップ

  1. [リリースページ](https://github.com/intersystems-ru/RESTForms/releases/tag/v1.0)で最新リリースである20161.xml( Caché 2016.1用)または201162.xml(Caché 2016.2以降用)をダウンロードして任意のネームスペースにインポートします。
  2. 新しいWebアプリケーション /forms をDispatchクラス Form.REST.Main を使用して作成します。
  3. http://localhost:57772/forms/test?Debug をブラウザで開き、インストールを検証します({"Status": "OK"} が出力され、場合によってはパスワードの入力が求められます)。
  4. テストデータが必要な場合は、次を呼び出します:

do ##class(Form.Util.Init).populateTestForms()

最初に、利用可能なクラスを知る必要があります。 この情報を取得するには、次を呼び出します。

http://localhost:57772/forms/form/info

次のような応答が返されます。

[
   { "name":"Company",     "class":"Form.Test.Company" },
   { "name":"Person",      "class":"Form.Test.Person"  },
   { "name":"Simple form", "class":"Form.Test.Simple"  }
]

現在3つのサンプルクラス(RESTFormで提供)があります。Person(Form.Test.Personクラス)のメタデータを見てみましょう。 この情報を取得するには、次を呼び出します。

http://localhost:57772/forms/form/info/Form.Test.Person

次のように、クラスのメタデータが応答として返されます。

{  
   "name":"Person",
   "class":"Form.Test.Person",
   "displayProperty":"name",
   "objpermissions":"CRUD",
   "fields":[  
      { "name":"name",     "type":"%Library.String",    "collection":"", "displayName":"Name",          "required":0, "category":"datatype" },
      { "name":"dob",      "type":"%Library.Date",      "collection":"", "displayName":"Date of Birth", "required":0, "category":"datatype" },
      { "name":"ts",       "type":"%Library.TimeStamp", "collection":"", "displayName":"Timestamp",     "required":0, "category":"datatype" },
      { "name":"num",      "type":"%Library.Numeric",   "collection":"", "displayName":"Number",        "required":0, "category":"datatype" },
      { "name":"аge",      "type":"%Library.Integer",   "collection":"", "displayName":"Age",           "required":0, "category":"datatype" },
      { "name":"relative", "type":"Form.Test.Person",   "collection":"", "displayName":"Relative",      "required":0, "category":"form"     },
      { "name":"Home",     "type":"Form.Test.Address",  "collection":"", "displayName":"House",         "required":0, "category":"serial"   },
      { "name":"company",  "type":"Form.Test.Company",  "collection":"", "displayName":"Company",       "required":0, "category":"form"     }
   ]
}

これらの情報は次のような意味を持ちます。

クラスのメタデータ:

  • name - クラスの表示名。
  • class - 基本となる永続クラス。
  • displayProperty - オブジェクトを表示するときに使用するオブジェクトのプロパティ。
  • objpermissions - ユーザーがオブジェクトを使用して実行できる操作。 この例では、ユーザーは新しいオブジェクトを作成し、既存のオブジェクトを変更し、既存のオブジェクトを削除し、次を取得できます。

プロパティのメタデータ:

  • name - プロパティ名 - クラスの定義と同じです。
  • type - プロパティのクラス。
  • * コレクション - リスト/配列のコレクションです。 * displayName - 表示プロパティ名。 * required - このプロパティが必須であるかどうか。 * category - プロパティのタイプクラスのカテゴリ。 RESTForms対応のすべてのクラスが「form」として表示されることを除き、通常のCachéクラスのカテゴリに従います。

    クラス定義では次のようになります。

    /// テストフォーム: Person
    Class Form.Test.Person Extends (%Persistent, Form.Adaptor, %Populate)
    {
    
    /// フォーム名。グローバルキーではないため、何でもかまいません。
    /// クラスをフォームとして持たないようにするには(ここのように)空の文字列に設定します。 
    Parameter FORMNAME = "Person";
    
    /// デフォルトの権限
    /// このフォームのオブジェクトは、作成、読み取り、更新、削除できます。
    /// すべてのユーザーの権限を変更するには、このパラメーターを再定義します。
    /// このクラスのcheckPermissionメソッドを再定義します(Form.Securityを参照してください)。
    /// ユーザーやロールなどに基づいて独自のセキュリティを追加します。
    Parameter OBJPERMISSIONS As %String = "CRUD";
    
    /// オブジェクトの基本情報に使用されるプロパティ
    /// デフォルトでは、getObjectDisplayNameメソッドはここから値を取得します。
    Parameter DISPLAYPROPERTY As %String = "name";
    
    /// このパラメーターの値をSQLでORDER BY句の値として使用します。 
    Parameter FORMORDERBY As %String = "dob";
    
    /// Personの名前。
    Property name As %String(COLLATION = "TRUNCATE(250)", DISPLAYNAME = "Name", MAXLEN = 2000);
    
    /// Personの生年月日。
    Property dob As %Date(DISPLAYNAME = "Date of Birth", POPSPEC = "Date()");
    
    Property ts As %TimeStamp(DISPLAYNAME = "Timestamp") [ InitialExpression = {$ZDATETIME($ZTIMESTAMP, 3, 1, 3)} ];
    
    Property num As %Numeric(DISPLAYNAME = "Number") [ InitialExpression = "2.15" ];
    
    /// Personの年齢。<br>
    /// これは、 <property>DOB</property> から派生した値を持つ計算されたフィールドです。
    Property аge As %Integer(DISPLAYNAME = "Age") [ Calculated, SqlComputeCode = { set {*}=##class(Form.Test.Person).currentAge({dob})}, SqlComputed, SqlComputeOnChange = dob ];
    
    /// このクラスメソッドは、誕生日 <var>date</var> が与えられた場合に現在の年齢を計算します。
    ClassMethod currentAge(date As %Date = "") As %Integer [ CodeMode = expression ]
    {
    $Select(date="":"",1:($ZD($H,8)-$ZD(date,8)\10000))
    }
    
    /// Personの配偶者。
    /// これは別の永続オブジェクトへの参照です。
    Property relative As Form.Test.Person(DISPLAYNAME = "Relative");
    
    /// Personの自宅住所。 埋め込みオブジェクトを使用します。
    Property Home As Form.Test.Address(DISPLAYNAME = "House");
    
    /// このPersonが働いている会社。
    Relationship company As Form.Test.Company(DISPLAYNAME = "Company") [ Cardinality = one, Inverse = employees ];
    }

    クラスでRESTFormsを有効にする

    そして、このクラスでRESTFormsを有効にするため、通常の永続クラスから始めて次のことを行いました。

    1. Form.Adaptor から拡張しました。
    2. 値を含むパラメーター FORMNAME(クラス名)を追加しました。
    3. OBJPERMISSIONS パラメーター(すべての権限のCRUD)を追加しました。
    4. DISPLAYPROPERTY パラメーター(オブジェクト名の表示に使用されるプロパティ名)を追加しました。
    5. FORMORDERBY パラメーター(RESTFormsを使用するクエリでソートするデフォルトのプロパティ)を追加しました。
    6. メタデータで確認したいプロパティごとに DISPLAYNAME プロパティのパラメーターを追加しました。

    以上です。 コンパイル後、RESTFormsを含むクラスを使用できるようになります。

    いくつかのテストデータを生成しましたので(インストールのステップ4を参照)、IDが1のPersonを取得してみましょう。 オブジェクトを取得するには、次を呼び出します。

    http://localhost:57772/forms/form/object/Form.Test.Person/1

    その応答は以下のとおりです(生成されるデータは異なる場合があります)。

    {
       "_class":"Form.Test.Person",
       "_id":1,
       "name":"Klingman,Rhonda H.",
       "dob":"1996-10-18",
       "ts":"2016-09-20T10:51:31.375Z",
       "num":2.15,
       "аge":20,
       "relative":null,
       "Home":{
          "_class":"Form.Test.Address",
          "House":430,
          "Street":"5337 Second Place",
          "City":"Jackson"
       },
       "company":{
          "_class":"Form.Test.Company",
          "_id":60,
          "name":"XenaSys.com",
          "employees":[
             null
          ]
       }
    }

    オブジェクト(具体的にはnumプロパティ)を変更するには、次を呼び出します。

    PUT http://localhost:57772/forms/form/object/Form.Test.Person

    このボディを使用します。

    {
       "_class":"Form.Test.Person",
       "_id":1,
       "num":3.15
    }

    速度を上げるには、_class_id、および変更対象のプロパティのみをリクエストのボディに含める必要があります。

    では、新しいオブジェクトを作成しましょう。 以下を呼び出します。

    POST http://localhost:57772/forms/form/object/Form.Test.Person

    このボディを使用します。

    {
       "_class":"Form.Test.Person",
        "name":"Test person",
        "dob":"2000-01-18",
        "ts":"2016-09-20T10:51:31.375Z",
        "num":2.15,
        "company":{ "_class":"Form.Test.Company", "_id":1 }
    }

    オブジェクトの作成が成功した場合、RESTFormsは以下のようにIDを返します。

    {"Id": "101"}

    成功しなかった場合、エラーがJSON形式で返されます。 すべての永続オブジェクトのプロパティは、 _class および _id プロパティによってのみ参照する必要があります。

    そして最後に、新しいオブジェクトを削除しましょう。 以下を呼び出します。

    DELETE http://localhost:57772/forms/form/object/Form.Test.Person/101

    これがForm.Test.Personクラスに対する完全なCRUDです。

    デモ

    [現在デモ環境はお試しいただくことができません。] こちらでRESTFormsをオンラインで試すことができます(ユーザー名:Demo、パスワード:Demo)。

    また、RESTFormsUIアプリケーション(RESTFormsデータエディタ)もあります。こちらをご確認ください(ユーザー名:Demo、パスワード:Demo)。 クラスリストのスクリーンショットを以下に掲載しています。

    まとめ

    RESTFormsは永続クラスに関する、REST APIから要求されるほとんどの機能を提供します。

    次の内容

    この記事では、RESTFormsの機能について説明しました。 次回の記事では、いくつかの高度な機能(クライアントからSQLインジェクションのリスクを冒さずにデータの一部を安全に取得できるクエリなど)についてお話ししたいと思います。 この記事のパート2でクエリに関する情報をお読みください

    RESTFormsUI(RESTFormsデータエディタ)もあります。

    リンク

    0
    0 344
    記事 Mihoko Iijima · 7月 6, 2020 18m read

    InterSystemsのテクノロジースタックを使用して独自のアプリを開発し、顧客側で複数のデプロイを実行したいとします。 開発プロセスでは、クラスをインポートするだけでなく、必要に応じて環境を微調整する必要があるため、アプリケーションの詳細なインストールガイドを作成しました。この特定のタスクに対処するために、インターシステムズは、%Installer(Caché/Ensemble)という特別なツールを作成しました 。 続きを読んでその使用方法を学んでください。

    %Installer

    このツールを使用すると、インストール手順ではなく、目的のCaché構成を記述するインストールマニフェストを定義できます。作成したい Caché 構成を記述します。必要な内容を記述するだけで、環境を変更するために必要なコードが自動的に生成されます。
    したがって、マニフェストのみを配布する必要がありますが、インストール・コードはすべてコンパイル時に特定の Caché サーバ用に生成されます。

    0
    0 551