Salesforce には Tooling API という非常に強力な API があります。
どのようなことができるかというと…

  • Apex クラスおよびトリガと Visualforce ページおよびコンポーネントの作業コピーを管理する。
  • 静的リソースファイルの作業コピーを管理する。
  • Apex クラスおよびトリガと Visualforce ページおよびコンポーネントの作業コピーに更新やエラーがないかチェックし、変更を組織にコミットする。
  • ヒープダンプマーカーを設定する。
  • Apex 実行時に Apex コードまたは SOQL ステートメントをフロート表示する。
  • Apex を匿名実行する。
  • チェックポイントを設定して自分または他のユーザ用にログファイルを生成する。
  • デバッグログおよびヒープダンプファイルにアクセスする。
  • カスタムオブジェクトのカスタム項目を管理する。
  • コードカバー率の結果にアクセスする。

*https://developer.salesforce.com/docs/atlas.ja-jp.salesforce1api.meta/salesforce1api/apis_tooling_introducing.htm より*

動的に生成されたApexクラスを追加するなど、そんなことが出来ていいのかというようなこともできてしまうようです。

この中で最近使用したのが、デバッグログへのアクセスです。
私の知る限りログ設定の有効期限は24時間が最大のため、24時間を超えてログを出力させたい場合は都度設定しなければなりません。
しかも、デバッグログはユーザごとに設定が必要なため、なにかの現象の再現待ちを行うなどで全ユーザにログを設定したいとなった場合には非常に手間がかかります。

そこで、以下のようなコードでデバッグログの設定を行いました。

Map<String, String> record = new Map<String, String>();
record.put('TracedEntityId', <ユーザのID>);
record.put('LogType', 'USER_DEBUG');
record.put('DebugLevelId', <デバッグレベルのID>);
record.put('ExpirationDate', DateTime.now().addDays(1).addHours(-9).format('yyyy-MM-dd\'T\'HH:mm:ss'));

Http h = new Http();
HttpRequest req = new HttpRequest();
req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
req.setHeader('Content-Type', 'application/json');
req.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v43.0/tooling/sobjects/TraceFlag/');
req.setMethod('POST');
req.setBody(JSON.serialize(record));
HttpResponse resp = h.send(req);

API を使用するときは認証をどうするかという問題がありますが、開発者コンソールの匿名ブロックで実行すれば現在のユーザのセッションIDが使用できます。
使用するオブジェクトは TraceLog です。デバッグログの設定はこのオブジェクトのレコードとして格納されています。

ExpirationDate で -9h しているのは、UTC で指定する必要があるためです。

なお実際のコードはもう少し複雑で、実際のコードでは、ユーザの一覧を取得してすでにそのユーザのデバッグログ設定があれば、ExpirationDate を更新するということも行っています。