Splunk SPL メモ

業務で Splunk の SPL をポチポチ触っているので メモなかなか覚えられない。


GitHub Enterprize の Audit ログを取り込んでいる Splunk があるのだが、

  • 特定の actor でフィルターする
  • action でカウントをとる
  • カウントを sort (昇順) する

をしたい。こんな SPL だった

`github_source` action=* actor="hiboma" 
|  stats count by action 
|  sort -count



データを並べ替えろ!|Splunk search コマンドでカスタムソートオーダー | Splunk

macOS: 構成プロファイルを CLI / Temirnal で確認する

macOS で構成プロファイルを CLI / Terminal で確認する方法を調べた

profiles コマンド

profiles list コマンドを使うといいらしい。 UUID のリストを取り出せた

 $ sudo profiles list -all
_computerlevel[1] attribute: profileIdentifier: 7652B8FE-93F6-427E-A132-4F0032BC2E25
_computerlevel[2] attribute: profileIdentifier: CE05F367-D6B1-44F5-BE4E-75092CC92CCF
_computerlevel[3] attribute: profileIdentifier: 00000000-0000-0000-A000-4A414D460003
_computerlevel[4] attribute: profileIdentifier: b6410f7f-7e37-48aa-b4ba-3b0532670ded
hito[5] attribute: profileIdentifier: F6FDEB75-31CB-48E1-849A-4A63DB0E310C
_computerlevel[6] attribute: profileIdentifier: 9BB724A3-3C4C-4678-B94A-7BD131E3533C
_computerlevel[7] attribute: profileIdentifier: 95307970-9F31-49A3-929E-38DD7FFE6798
_computerlevel[8] attribute: profileIdentifier: 4832ABA3-49D0-41EE-A154-740AABB187CB
_computerlevel[9] attribute: profileIdentifier: B6CA5188-4CE3-4E0E-A7FD-926D691F6ECA
_computerlevel[10] attribute: profileIdentifier: 5FEA911C-C63C-4568-A567-9D3AFF96FA84
_computerlevel[11] attribute: profileIdentifier: AD23B302-7FA9-40A8-ABEE-6BE1E75B7252
_computerlevel[12] attribute: profileIdentifier: BB3C1710-A7FB-4465-9433-B05AF0F62F98
_computerlevel[13] attribute: profileIdentifier: 2E9C4A81-5839-4DFA-A03F-3CF389DE927F
_computerlevel[14] attribute: profileIdentifier: C70479F3-F6FB-4839-8347-C1C8C10F5648
_computerlevel[15] attribute: profileIdentifier: B04EAFC1-48DA-461D-9DA2-4A2593BEFB5C
_computerlevel[16] attribute: profileIdentifier: com.jamf.notifications.settings
_computerlevel[17] attribute: profileIdentifier: 4a90db4f-aa61-4909-8f45-d72e204733f9
_computerlevel[18] attribute: profileIdentifier: com.jamfsoftware.tcc.management
There are 18 configuration profiles installed

profiles show を実行すると構成プロファイルの詳細が取り出せる。下記は Jamf で配布した構成プロファイルです。

$ sudo profiles show 


_computerlevel[2] attribute: name: Falcon Notifactions
_computerlevel[2] attribute: installationDate: 2022-10-07 02:24:49 +0000
_computerlevel[2] attribute: organization: ***
_computerlevel[2] attribute: profileIdentifier: BB3C1710-A7FB-4465-9433-B05AF0F62F98
_computerlevel[2] attribute: profileUUID: BB3C1710-A7FB-4465-9433-B05AF0F62F98
_computerlevel[2] attribute: profileType: Configuration
_computerlevel[2] attribute: removalDisallowed: TRUE
_computerlevel[2] attribute: version: 1
_computerlevel[2] attribute: containsComputerItems: TRUE
_computerlevel[2] attribute: installedByMDM: TRUE
_computerlevel[2] attribute: internaldata: TRUE
_computerlevel[2] payload count = 1
_computerlevel[2]            payload[1] name            = Notifications Payload
_computerlevel[2]            payload[1] description     = (null)
_computerlevel[2]            payload[1] type            = com.apple.notificationsettings
_computerlevel[2]            payload[1] organization        = JAMF Software
_computerlevel[2]            payload[1] identifier      = C462E5FD-60CC-43D9-B91F-423C330C3513
_computerlevel[2]            payload[1] uuid            = 382A2208-A159-46EC-96F2-76FC2C00CAF3

man はこんな感じ ( man profiles | col -b | pbcopy で出した ) 色々サブコマンドがついているが、細かくは調べていない

profiles(1)           General Commands Manual             profiles(1)

     profiles - Profiles Tool for macOS.

     profiles verb [options]

     profiles is used to handle various profile types on macOS.   Starting with
     macOS 11.0 (profiles tool 8.0 or later), this tool cannot be
     used to install configuration profiles.  You should add your profiles
     using the System Preferences Profiles
     preference pane.    Additionally, startup profiles are no longer

     Each command verb is listed with its description and optional individual
     arguments.   Most commands use the -type option to determine which kind of
     profile should be used in the command.  For those commands, if no type is
     specified, the default will be to use the configuration profile type.

        Shows abbreviated help

     list   -type profile_type -user user_name -output output_path
        List profiles for a user or when running as root, the device.

     show   -type profile_type -user user_name -output output_path
        Show expanded information for profiles.   For an enrollment,
        this will show the current DEP configuration, and the call may
        be rate limited to once every 23 hours.

     remove -type profile_type -user user_name -identifier identifier -uuid
        uuid -path file_path -forced -all
        Remove profiles. Attempting to remove a configuration profile
        requring a removal password without the correct password will

     status -type profile_type
        Display status of the profiles installed on this client.   When
        displaying the enrollment type status, if the MDM enrollment was
        user approved, the status output will show "(User Approved)".

     sync   -type configuration
        For configuration profiles, synchronize current installed set of
        profiles with the local users and remove any configuration
        profiles that belong to users that no longer exist on this

     renew  -type profile_type -identifier identifier -output output_path
        For configuration profiles, renews any certificates for the
        specified profile.  For Device Enrollment Program (DEP)
        enrollments, retry to obtain the device enrollment
        configuration, and re-enable the user notification if enrollment
        wasn't completed.

     validate   -type profile_type -path file_path
        For provisioning profiles, validate the provisioning profile
        located at the file_path.  For enrollments, re-validate the
        installed DEP server information and update any local
        information, displaying any major changes.  If this information
        is different from the current enrolled server, this will not
        unenroll the client from the current server.  This call may be
        rate limited to once every 23 hours.

        Displays current tool version.

     -type profile_type
         The profile_type can be one of either: "configuration",
         "provisioning", "bootstraptoken", or "enrollment" (DEP).  If a
         command requires a profile type and none is specified,
         "configuration" will be used.

     -path file_path
         A file path or "-" to represent stdout.   When used by the remove
         command for startup profiles, this should only contain the file
         name of the profile.

     -user user_name
         An OD short user name.   In most cases if no user was specified,
         then the current user will be used.   If no user option was
         specified and the process runs as root, the computer/device
         profiles will be used in the command.

     -uuid profile_uuid
         A canonical form UUID to specify a profile's PayloadUUID, such as
         5A15247B-899C-474D-B1D7-DBD82BDE5684.   Only used by the remove
         provisioning profile command.

     -identifier profile_identifier
         A profile identifier (PayloadIdentifier) to specify a profile.

     -output output_path
         The output path location.  The output_path argument must be
         specified to use this option, Use 'stdout' to send this informaton
         to the console.  File output will be written as an XML plist file,
         or you can use 'stdout-xml' to write XML to the console.  The
         toplevel key of the dictionary will contain either the user name,
         or _computerLevel for device or provisioning profile information.

     -password password
         An optional password used when removing a configuration profile
         which requires the password removal option.

         This will prevent confirmation requests, and when trying to remove
         all configuration profles for a user, it will ignore any errors
         during removal.

     -all    For configuration profiles, when running as root, the use of this
         option with the list or show commands will display all profiles
         installed on the system.   When removing profiles, using this
         option will remove all profiles for that user (or device).

         Display additional information.

         A configuration profile.

         A provisioning profile.

         A device enrollment program (DEP) or mobile device management (MDM)
         enrollment profile or feature.

         Bootstrap Token options.   Requires MDM supervised client.

     profiles remove -path /profiles/testfile2.mobileconfig
          Removes the configuration profile file
          '/profiles/testfile2.mobileconfig' into the current user.

     profiles list -type provisioning
          Displays a list of installed provisioning profiles.

     profiles list -all
          When running as root, this will list all configuration profiles on
          the system.

     profiles show
          Displays extended information for installed configuration profiles
          for the current user.

     profiles status -type startup
          Displays information on whether or not startup profiles are set

     profiles remove -identifier com.example.profile1 -password pass
          Removes any installed profiles with the identifier
          com.example.profile1 in the current user and using a removal
          password of 'pass'.

     profiles show -type enrollment
          Displays the current DEP configuration information.

     profiles renew -type enrollment
          Re-enables the DEP user notification enrollment messages.

     profiles install -type bootstraptoken
          Creates or updates the Bootstrap Token APFS record and escrows the
          information to the server.


macOS               November 30, 2021              macOS








man profiles | pbcopy だと余計な文字が入り困ったのだが、下記のエントリを参考にして解決しました


夏休み 猪苗代湖〜磐梯吾妻スカイライン〜福島駅 🚴

夏休みの記録。8/11 に猪苗代湖磐梯吾妻スカイライン(途中で引き返し) 〜福島市 を走った記録

Garmin を途中で間違って止めてしまったので記録が二つに分かれている

走行距離 179km 獲得標高 1900m でお腹いっぱいライド


那須塩原 〜 東京 🚴

8/7 (日) 4号線をずっと南下して東京駅まで走った。帰りは新幹線。

走行距離 154km 獲得標高 345m 走行時間 6時間11分 ( 経過時間 8時間44分 )

四号線を使って東京まで走ったのは 2回目。下は以前の記録



帰りは新幹線なすのに乗って帰宅。日曜夕方 東京発の なすのはガラガラで、客席に自転車を持ち込んでも迷惑にならない。

その他 感想




飛ばしたい車や大型車は新四号を使うっぽいので、(旧) 四号線はのんびり流れている。路肩もそんなに狭くなくて安全。


狭い + 路面の状態も悪くて凸凹も多い。しんどい!


軽〜い向かい風がずっと吹いていて、風の恩恵は受けられなかったなー Garmin Edge だと 平均 25.2km 時で記録されていて Strava だと 平均 24.9km/時 の記録だった

涼しい時だと もう少し速く走れんかな

slack: metadata で構造化されたデータを扱う - bot 間の連携に使う実装例

slack で bot を動かしていて 「 別の bot のメッセージに反応して何かする bot を書くユースケースがあります *1


例えば こんな メッセージを出す bot がいるとします *2

上記の メッセージ から UUID ( OpenStack の Server UUID ) を取り出して、別の bot で何か処理をしたい場合を考えましょう

  • text を抜き出して正規表現で UUID のマッチを試みる
  • attachments や blocks の Hash/Array をイテレートして UUID を取り出す



非構造化されたデータ を扱うのは何かと面倒で変更にも弱いですね

元のメッセージのフォーマットが変わる ( text の内容が変わる, attachments や blocks の構造が変わる ) と bot を再実装する必要が出そうです 。人間向けの view に依存してるコードは実装が複雑になったり、メンテナンス性が下がります。スクレイピングのコードを書いたことのある人はよくわかるかと思います。

botbot のメッセージを扱う場合に、構造化されたデータ ( Hash, Array ) で扱えると楽だよなぁと.... 長らく思っていたのでした。

metadata を使おう

で、改めて Slack のドキュメントを調べてみたら、メッセージに metadata として Hash 構造のデータを付けられるのを この度 知ったのでした。


今年の4月頃に出ていたのかな? *3

metadata の例

下記のように metadataevent_typeevent_payload を入れてメッセージを POST できる!

    "channel": "C23456",
    "text": "New teammate @Billy just joined",
    "metadata": {
        "event_type": "new_teammate",
        "event_payload": {
            "id": "TK-2132",
            "summary": "New teammate has been added to the channel",
            "description": "@Billy is a new teammate and needs to be added to the neccesary channels",
            "priority": "HIGH",
            "resource_ type": "TASK"

別の bot のメッセージに反応して何かする bot を作る際、metadata を参照すると構造化されたデータで扱いやすそう (ただし メッセージを出す bot で metadata を付与してないといけないけど ... )

metadata を使った、別の bot のメッセージに反応して何かする bot 実装例

  • metadata 付きのメッセージを通知する Ruby アプリ
  • metadata 付きのメッセージに反応する Python Bolt アプリ


metadata 付きのメッセージを通知する Ruby アプリ

↑ のようなメッセージを POST する単純なコードです。metadata も付けています。

#!/usr/bin/env ruby

require 'slack-ruby-client'
require 'dotenv'


params = {
  channel: '#dev',
  username: 'live-migration-notifier',
  text: ":arrow_forward: live-migrationが開始されました",
  blocks: [
      type: :section,
      text: {
        type: :plain_text,
        text: ":arrow_forward: live-migrationが開始されました",
        emoji: true
      type: :divider,
      type: :context,
      elements: [
          type: :mrkdwn,
          text: ":desktop_computer: *example.com*\n:pencil2: 7ef9111c-0000-0000-0000-1717950e45cf",
          verbatim: true
      type: :context,
      elements: [
          type: :plain_text,
          text: ":outbox_tray: host000",
          emoji: true
          type: :plain_text,
          text: ":inbox_tray: host001",
          emoji: true
      type: :divider,
      type: :context,
      elements: [
          type: :plain_text,
          text: "req-b23c7b63-0000-0000-0000-00000000",
          emoji: false
          type: :plain_text,
          text: "by instance-migrator",
          emoji: false

# こんな感じで 構造化したデータを突っ込める
metadata = {
  event_type: "live_migration_started",
  event_payload: {
    source_host: "host000",
    dest_host: "host001",
    server: {
      name: "example.com",
      uuid: "7ef9111c-0000-0000-0000-1717950e45cf",

# metadata には JSON を入れる
params[:metadata] = metadata.to_json

client = Slack::Web::Client.new(token: ENV['SLACK_API_TOKEN'])

metadata 付きのメッセージに反応する Python Bolt アプリ

先のメッセージに反応する Python Bolt アプリです。

import os

import dotenv
import slack_bolt
from slack_bolt.adapter.socket_mode import SocketModeHandler


app = slack_bolt.App(token=os.environ["SLACK_BOT_TOKEN"])

def handle_message(event, say):
    metadata = event.get("metadata")
    if metadata is None:

    if metadata["event_type"] == "live_migration_started":
        payload = metadata["event_payload"]


        server_name = payload["server"]["name"]
        server_uuid = payload["server"]["uuid"]
        say("{0} {1} started live-migration".format(server_name, server_uuid))

if __name__ == "__main__":
    handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"])


二つの bot が連携して動作している例です

Python Bolt アプリでは、以下のように metadata を受け取っています

 $ poetry run python bot.py
⚡️ Bolt app is running!
{'source_host': 'host000', 'dest_host': 'host001', 'server': {'name': 'example.com', 'uuid': '7ef9111c-0000-0000-0000-1717950e45cf'}}


Proof Of Concent なコードなので、特に利用価値がある実装ではありません。 metadata を通して依存関係を持っている、ってのがポイントですね。



  • Emoji で Reaction 付けたら、メッセージの metadata ( event_type, event_payload ) を取り出して何か操作するってコード書けそう

metadata の 技術的な疑問点

  • OSS なんかで汎用的に使う bot の場合、 event_type命名はどう扱うのがいいのだろうか?
    • あまり単純な名前をつけると、別の bot と衝突するだろう
    • namespace の規約があるといいようには思う


  • live-migration-notifier の通知を別チャンネルにも転送したいユースケースがあった
  • live-migration-notifier に機能を追加するよりも、別の bot で転送機能実装したらいいかと思って 「 別の bot のメッセージに反応して何かする bot 」を書いていた

*1:何らかの理由で 元のメッセージを出す bot の実装を変えたくない/変えられない場合

*2:同僚の id:buty4649 が書いた OpenStackのLiveMigrationの通知するくん のメッセージです github.com

*3: このエントリを書いている時点では open beta の機能です

lsof でファイルオープンのフラグを確認できる


↑ 同僚のエントリを読んで 早速調べものをしていたのだが、8進数で書かれたフラグを理解するのがちょっと大変。 lsof あたりで人間が読みやすくするようにサポートしてないのかな? ... と調べたらあった!

lsof +f g オプション

lsof に +f g って付ける良い。以下は apache2 の lsof をとった内容

$ sudo lsof +f g -p 5087 | tail
apache2 5087 www-data  DEL       REG                    0,5             32893 /dev/zero
apache2 5087 www-data    0r      CHR              LG    1,3      0t0        6 /dev/null
apache2 5087 www-data    1w      CHR            W,LG    1,3      0t0        6 /dev/null
apache2 5087 www-data    2w      REG         W,AP,LG  252,0      739 35389666 /var/log/apache2/error.log
apache2 5087 www-data    3u     IPv4   RW,ND,0x80000  67450      0t0      TCP *:http (LISTEN)
apache2 5087 www-data    4r     FIFO         0x80000   0,10      0t0    32892 pipe
apache2 5087 www-data    5w     FIFO       W,0x80000   0,10      0t0    32892 pipe
apache2 5087 www-data    6w      REG W,AP,LG,0x80000  252,0        0 35389607 /var/log/apache2/other_vhosts_access.log
apache2 5087 www-data    7w      REG W,AP,LG,0x80000  252,0        0 35389605 /var/log/apache2/access.log
apache2 5087 www-data    8u  a_inode      RW,0x80000   0,11        0    12000 [eventpoll]

フラグは略記されており、それぞれの読み方は man に書いてあります

       FILE-FLAG  when  g or G has been specified to +f, this field contains the contents of the f_flag[s] member of the kernel file structure and the kernel's per-process open file flags (if available); `G'
                  causes them to be displayed in hexadecimal; `g', as short-hand names; two lists may be displayed with entries separated by commas, the lists separated by a semicolon (`;'); the  first  list
                  may contain short-hand names for f_flag[s] values from the following table:

                       AIO       asynchronous I/O (e.g., FAIO)
                       AP        append
                       ASYN      asynchronous I/O (e.g., FASYNC)
                       BAS       block, test, and set in use
                       BKIU      block if in use
                       BL        use block offsets
                       BSK       block seek
                       CA        copy avoid
                       CIO       concurrent I/O
                       CLON      clone
                       CLRD      CL read
                       CR        create
                       DF        defer
                       DFI       defer IND
                       DFLU      data flush
                       DIR       direct
                       DLY       delay
                       DOCL      do clone
                       DSYN      data-only integrity
                       DTY       must be a directory
                       EVO       event only
                       EX        open for exec
                       EXCL      exclusive open
                       FSYN      synchronous writes
                       GCDF      defer during unp_gc() (AIX)
                       GCMK      mark during unp_gc() (AIX)
                       GTTY      accessed via /dev/tty
                       HUP       HUP in progress
                       KERN      kernel
                       KIOC      kernel-issued ioctl
                       LCK       has lock
                       LG        large file
                       MBLK      stream message block
                       MK        mark
                       MNT       mount
                       MSYN      multiplex synchronization
                       NATM      don't update atime
                       NB        non-blocking I/O
                       NBDR      no BDRM check
                       NBIO      SYSV non-blocking I/O
                       NBF       n-buffering in effect
                       NC        no cache
                       ND        no delay
                       NDSY      no data synchronization
                       NET       network
                       NFLK      don't follow links
                       NMFS      NM file system
                       NOTO      disable background stop
                       NSH       no share
                       NTTY      no controlling TTY
                       OLRM      OLR mirror
                       PAIO      POSIX asynchronous I/O
                       PP        POSIX pipe
                       R         read
                       RC        file and record locking cache
                       REV       revoked
                       RSH       shared read
                       RSYN      read synchronization
                       RW        read and write access
                       SL        shared lock
                       SNAP      cooked snapshot
                       SOCK      socket
                       SQSH      Sequent shared set on open
                       SQSV      Sequent SVM set on open
                       SQR       Sequent set repair on open
                       SQS1      Sequent full shared open
                       SQS2      Sequent partial shared open
                       STPI      stop I/O
                       SWR       synchronous read
                       SYN       file integrity while writing
                       TCPM      avoid TCP collision
                       TR        truncate
                       W         write
                       WKUP      parallel I/O synchronization
                       WTG       parallel I/O synchronization
                       VH        vhangup pending
                       VTXT      virtual text
                       XL        exclusive lock

                  this  list  of names was derived from F* #define's in dialect header files <fcntl.h>, <linux</fs.h>, <sys/fcntl.c>, <sys/fcntlcom.h>, and <sys/file.h>; see the lsof.h header file for a list
                  showing the correspondence between the above short-hand names and the header file definitions;

                  the second list (after the semicolon) may contain short-hand names for kernel per-process open file flags from this table:

                       ALLC      allocated
                       BR        the file has been read
                       BHUP      activity stopped by SIGHUP
                       BW        the file has been written
                       CLSG      closing
                       CX        close-on-exec (see fcntl(F_SETFD))
                       LCK       lock was applied
                       MP        memory-mapped
                       OPIP      open pending - in progress
                       RSVW      reserved wait
                       SHMT      UF_FSHMAT set (AIX)
                       USE       in use (multi-threaded)