Repository: scale-tone/DurableFunctionsMonitor
Branch: master
Commit: 6acaded3c44f
Files: 201
Total size: 2.8 MB
Directory structure:
gitextract_sz7kn825/
├── .gitignore
├── LICENSE
├── README.md
├── azure-pipelines.yml
├── custom-backends/
│ ├── README.md
│ ├── mssql/
│ │ ├── .gitignore
│ │ ├── Dfm.MsSql.csproj
│ │ ├── README.md
│ │ ├── Startup.cs
│ │ ├── arm-template.json
│ │ └── host.json
│ ├── netcore21/
│ │ ├── .gitignore
│ │ ├── Dfm.NetCore21.csproj
│ │ ├── README.md
│ │ ├── Startup.cs
│ │ ├── arm-template.json
│ │ └── host.json
│ └── netcore31/
│ ├── .gitignore
│ ├── Dfm.NetCore31.csproj
│ ├── README.md
│ ├── Startup.cs
│ ├── arm-template.json
│ └── host.json
├── durablefunctionsmonitor-vscodeext/
│ ├── .gitignore
│ ├── .vscode/
│ │ ├── extensions.json
│ │ ├── launch.json
│ │ ├── settings.json
│ │ └── tasks.json
│ ├── .vscodeignore
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── src/
│ │ ├── BackendProcess.ts
│ │ ├── ConnStringUtils.ts
│ │ ├── FunctionGraphList.ts
│ │ ├── FunctionGraphView.ts
│ │ ├── MonitorTreeDataProvider.ts
│ │ ├── MonitorView.ts
│ │ ├── MonitorViewList.ts
│ │ ├── Settings.ts
│ │ ├── SharedConstants.ts
│ │ ├── StorageAccountTreeItem.ts
│ │ ├── StorageAccountTreeItems.ts
│ │ ├── SubscriptionTreeItem.ts
│ │ ├── SubscriptionTreeItems.ts
│ │ ├── TaskHubTreeItem.ts
│ │ ├── az-func-as-a-graph/
│ │ │ ├── FunctionsMap.d.ts
│ │ │ ├── traverseFunctionProject.ts
│ │ │ └── traverseFunctionProjectUtils.ts
│ │ ├── extension.ts
│ │ └── test/
│ │ ├── runTest.ts
│ │ └── suite/
│ │ ├── extension.test.ts
│ │ └── index.ts
│ ├── tsconfig.json
│ └── tslint.json
├── durablefunctionsmonitor.dotnetbackend/
│ ├── .gitignore
│ ├── .vscode/
│ │ ├── extensions.json
│ │ ├── launch.json
│ │ ├── settings.json
│ │ └── tasks.json
│ ├── Common/
│ │ ├── Auth.cs
│ │ ├── CustomTemplates.cs
│ │ ├── DetailedOrchestrationStatus.cs
│ │ ├── ExpandedOrchestrationStatus.cs
│ │ ├── FilterClause.cs
│ │ ├── Globals.cs
│ │ ├── HttpHandlerBase.cs
│ │ ├── OrchestrationHistory.cs
│ │ ├── Setup.cs
│ │ └── TableClient.cs
│ ├── DfmStatics/
│ │ ├── index.html
│ │ ├── manifest.json
│ │ └── static/
│ │ ├── css/
│ │ │ ├── 2.62e7949a.chunk.css
│ │ │ └── main.12374d2f.chunk.css
│ │ └── js/
│ │ ├── 2.7e622828.chunk.js
│ │ ├── 2.7e622828.chunk.js.LICENSE.txt
│ │ ├── main.7371b08e.chunk.js
│ │ └── runtime-main.edc3f937.js
│ ├── Dockerfile
│ ├── Functions/
│ │ ├── About.cs
│ │ ├── CleanEntityStorage.cs
│ │ ├── DeleteTaskHub.cs
│ │ ├── EasyAuthConfig.cs
│ │ ├── FunctionMap.cs
│ │ ├── IdSuggestions.cs
│ │ ├── ManageConnection.cs
│ │ ├── Orchestration.cs
│ │ ├── Orchestrations.cs
│ │ ├── PurgeHistory.cs
│ │ ├── ServeStatics.cs
│ │ └── TaskHubNames.cs
│ ├── LICENSE
│ ├── NUGET_README.md
│ ├── README.md
│ ├── arm-template.json
│ ├── dfm-aks-deployment.yaml
│ ├── durablefunctionsmonitor.dotnetbackend.csproj
│ ├── durablefunctionsmonitor.dotnetbackend.targets
│ ├── host.json
│ ├── nuspec.nuspec
│ ├── proxies.json
│ └── setup-and-run.js
├── durablefunctionsmonitor.functions/
│ └── README.md
├── durablefunctionsmonitor.react/
│ ├── .gitignore
│ ├── README.md
│ ├── copy-build-artifacts.js
│ ├── package.json
│ ├── public/
│ │ ├── index.html
│ │ └── manifest.json
│ ├── src/
│ │ ├── CancelToken.ts
│ │ ├── DateTimeHelpers.ts
│ │ ├── DfmContext.ts
│ │ ├── components/
│ │ │ ├── ErrorMessage.css
│ │ │ ├── ErrorMessage.tsx
│ │ │ ├── FunctionGraph.css
│ │ │ ├── FunctionGraph.tsx
│ │ │ ├── FunctionGraphBase.tsx
│ │ │ ├── FunctionGraphTabBase.tsx
│ │ │ ├── LoginIcon.css
│ │ │ ├── LoginIcon.tsx
│ │ │ ├── Main.css
│ │ │ ├── Main.tsx
│ │ │ ├── MainMenu.css
│ │ │ ├── MainMenu.tsx
│ │ │ ├── OrchestrationLink.tsx
│ │ │ ├── SaveAsSvgButton.tsx
│ │ │ ├── details-view/
│ │ │ │ ├── DurableEntityButtons.tsx
│ │ │ │ ├── DurableEntityFields.tsx
│ │ │ │ ├── OrchestrationButtons.tsx
│ │ │ │ ├── OrchestrationDetails.css
│ │ │ │ ├── OrchestrationDetails.tsx
│ │ │ │ ├── OrchestrationDetailsFunctionGraph.tsx
│ │ │ │ └── OrchestrationFields.tsx
│ │ │ ├── dialogs/
│ │ │ │ ├── CleanEntityStorageDialog.css
│ │ │ │ ├── CleanEntityStorageDialog.tsx
│ │ │ │ ├── ConnectionParamsDialog.tsx
│ │ │ │ ├── LongJsonDialog.tsx
│ │ │ │ ├── PurgeHistoryDialog.css
│ │ │ │ ├── PurgeHistoryDialog.tsx
│ │ │ │ ├── StartNewInstanceDialog.css
│ │ │ │ └── StartNewInstanceDialog.tsx
│ │ │ └── results-view/
│ │ │ ├── Orchestrations.css
│ │ │ ├── Orchestrations.tsx
│ │ │ ├── OrchestrationsFunctionGraph.css
│ │ │ ├── OrchestrationsFunctionGraph.tsx
│ │ │ ├── OrchestrationsGanttChart.tsx
│ │ │ ├── OrchestrationsHistogram.tsx
│ │ │ └── OrchestrationsList.tsx
│ │ ├── index.css
│ │ ├── index.tsx
│ │ ├── react-app-env.d.ts
│ │ ├── services/
│ │ │ ├── BackendClient.ts
│ │ │ ├── IBackendClient.ts
│ │ │ └── VsCodeBackendClient.ts
│ │ ├── states/
│ │ │ ├── DurableOrchestrationStatus.ts
│ │ │ ├── ErrorMessageState.ts
│ │ │ ├── FilterOperatorEnum.ts
│ │ │ ├── FunctionGraphState.ts
│ │ │ ├── FunctionGraphStateBase.ts
│ │ │ ├── ITypedLocalStorage.ts
│ │ │ ├── LoginState.ts
│ │ │ ├── MainMenuState.ts
│ │ │ ├── MainState.ts
│ │ │ ├── MermaidDiagramStateBase.ts
│ │ │ ├── QueryString.ts
│ │ │ ├── TypedLocalStorage.ts
│ │ │ ├── VsCodeTypedLocalStorage.ts
│ │ │ ├── az-func-as-a-graph/
│ │ │ │ ├── FunctionsMap.d.ts
│ │ │ │ └── buildFunctionDiagramCode.ts
│ │ │ ├── details-view/
│ │ │ │ ├── FunctionGraphTabState.ts
│ │ │ │ ├── GanttDiagramTabState.ts
│ │ │ │ ├── ICustomTabState.ts
│ │ │ │ ├── LiquidMarkupTabState.ts
│ │ │ │ ├── MermaidDiagramTabState.ts
│ │ │ │ ├── OrchestrationDetailsState.ts
│ │ │ │ └── SequenceDiagramTabState.ts
│ │ │ ├── dialogs/
│ │ │ │ ├── CleanEntityStorageDialogState.ts
│ │ │ │ ├── ConnectionParamsDialogState.ts
│ │ │ │ ├── PurgeHistoryDialogState.ts
│ │ │ │ └── StartNewInstanceDialogState.ts
│ │ │ └── results-view/
│ │ │ ├── OrchestrationsState.ts
│ │ │ ├── ResultsFunctionGraphTabState.ts
│ │ │ ├── ResultsGanttDiagramTabState.ts
│ │ │ ├── ResultsHistogramTabState.ts
│ │ │ └── ResultsListTabState.ts
│ │ └── theme.ts
│ ├── tsconfig.json
│ └── tslint.json
└── tests/
└── durablefunctionsmonitor.dotnetbackend.tests/
├── .gitignore
├── .vscode/
│ ├── launch.json
│ └── tasks.json
├── AboutTests.cs
├── AuthTests.cs
├── EasyAuthConfigTests.cs
├── FilterClauseTests.cs
├── GlobalsTests.cs
├── IdSuggestionsTests.cs
├── ServeStaticsTests.cs
├── Shared.cs
└── durablefunctionsmonitor.dotnetbackend.tests.csproj
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.vs
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2019 scale-tone
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
***
# THIS PROJECT HAS MOVED TO https://github.com/microsoft/DurableFunctionsMonitor
***

# Durable Functions Monitor
A monitoring/debugging UI tool for Azure Durable Functions
[Azure Durable Functions](https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-overview) provide an easy and elegant way of building cloud-native Reliable Stateful Services in the Serverless world. The only thing that's missing so far is a UI for monitoring, managing and debugging your orchestration instances. This project tries to bridge the gap.
[](https://www.nuget.org/profiles/durablefunctionsmonitor)
[
](https://marketplace.visualstudio.com/items?itemName=DurableFunctionsMonitor.durablefunctionsmonitor) [
](https://hub.docker.com/r/scaletone/durablefunctionsmonitor) [
](https://www.nuget.org/profiles/durablefunctionsmonitor)
# Prerequisites
To run this on your devbox you need to have [Azure Functions Core Tools](https://www.npmjs.com/package/azure-functions-core-tools) **globally** installed (which is normally already the case, if you're working with Azure Functions - just ensure that you have the latest version of it).
**OR**
[Docker Desktop](https://www.docker.com/products/docker-desktop), if you prefer to run it locally [as a container](https://hub.docker.com/r/scaletone/durablefunctionsmonitor).
# How to run
As a [VsCode Extension](https://github.com/scale-tone/DurableFunctionsMonitor/blob/master/durablefunctionsmonitor-vscodeext/README.md#durable-functions-monitor-as-a-vscode-extension).
* Install it [from the Marketplace](https://marketplace.visualstudio.com/items?itemName=DurableFunctionsMonitor.durablefunctionsmonitor) or from [a VSIX-file](https://github.com/scale-tone/DurableFunctionsMonitor/releases).
* (if you have [Azure Functions](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions) extension also installed) Goto **Azure Functions**
View Container, observe all your TaskHubs under **DURABLE FUNCTIONS** tab and click on them to connect.
* (if not) Type `Durable Functions Monitor` in your Command Palette and then confirm or provide Storage Connection String and Hub Name.
**OR**
[As a standalone service](https://github.com/scale-tone/DurableFunctionsMonitor/blob/master/durablefunctionsmonitor.dotnetbackend/README.md#durablefunctionsmonitordotnetbackend), either running locally on your devbox or deployed into Azure: [](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fscale-tone%2FDurableFunctionsMonitor%2Fmaster%2Fdurablefunctionsmonitor.dotnetbackend%2Farm-template.json)
**OR**
[Install it as a NuGet package](https://www.nuget.org/packages/DurableFunctionsMonitor.DotNetBackend) into your own Functions project (.Net Core only).
# Features
## 1. View the list of your Orchestrations and/or Durable Entities, with sorting, infinite scrolling and auto-refresh:
## 2. Filter by time range and column values:
## 3. Visualize the filtered list of instances as a Time Histogram or as a Gantt chart:
## 4. Start new orchestration instances:
## 5. Monitor the status of a certain instance:
## 6. Quickly navigate to a certain instance by its ID:
## 7. Observe Sequence Diagrams and Gantt Charts for orchestrations:
## 8. Restart, Purge, Rewind, Terminate, Raise Events, Set Custom Status:
## 9. Purge Orchestration/Entity instances history:
## 10. Clean deleted Durable Entities:
## 11. Create custom Orchestration/Entity status tabs with [Liquid Templates](https://shopify.github.io/liquid/):
1. Create a [Liquid](https://shopify.github.io/liquid/) template file and name it like `[My Custom Tab Name].[orchestration-or-entity-name].liquid` or just `[My Custom Tab Name].liquid` (this one will be applied to any kind of entity).
2. In the same Storage Account (the account where your Durable Functions run in) create a Blob container called `durable-functions-monitor`.
3. Put your template file into a `tab-templates` virtual folder in that container (the full path should look like `/durable-functions-monitor/tab-templates/[My Custom Tab Name].[orchestration-or-entity-name].liquid`).
4. Restart Durable Functions Monitor.
5. Observe the newly appeared `My Custom Tab Name` tab on the Orchestration/Entity Details page:
Sample Liquid Template:
```
## 13. Monitor non-default Storage Providers (Netherite, Microsoft SQL, etc.):
For that you can use Durable Functions Monitor in 'injected' mode, aka added as a [NuGet package](https://www.nuget.org/profiles/durablefunctionsmonitor) to *your* project.
1. Create a .Net Core Function App project, that is [configured to use an alternative Storage Provider](https://docs.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-storage-providers#azure-storage) and make sure it compiles and starts.
2. Add [DurableFunctionsMonitor.DotNetBackend](https://www.nuget.org/profiles/durablefunctionsmonitor) package to it:
```
dotnet add package DurableFunctionsMonitor.DotNetBackend
```
4. Add mandatory initialization code, that needs to run at your Function's startup:
```
[assembly: WebJobsStartup(typeof(StartupNs.Startup))]
namespace StartupNs
{
public class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
DfmEndpoint.Setup();
}
}
}
```
Find more details on programmatic configuration options in the [package readme](https://www.nuget.org/packages/DurableFunctionsMonitor.DotNetBackend/).
6. Run the project:
```
func start
```
8. Navigate to `http://localhost:7071/api`.
You can customize the endpoint address as needed, as described [here](https://www.nuget.org/packages/DurableFunctionsMonitor.DotNetBackend/).
## 14. Visualize your Azure Function projects in form of an interactive graph:
This functionality is powered by [az-func-as-a-graph](https://github.com/scale-tone/az-func-as-a-graph/blob/main/README.md) tool, but now it is also fully integrated into Durable Functions Monitor:

When running Durable Functions Monitor as [VsCode Extension](https://marketplace.visualstudio.com/items?itemName=DurableFunctionsMonitor.durablefunctionsmonitor), the **Functions Graph** tab should appear automatically, once you have the relevant Functions project opened.
When running in [standalone/injected mode](https://github.com/scale-tone/DurableFunctionsMonitor/tree/master/durablefunctionsmonitor.dotnetbackend#how-to-run) you'll need to generate and upload an intermediate Functions Map JSON file.
1. Generate it with [az-func-as-a-graph CLI](https://github.com/scale-tone/az-func-as-a-graph/blob/main/README.md#how-to-run-as-part-of-azure-devops-build-pipeline). Specify `dfm-func-map.
- Should now work seamlessly in [GitHub Codespaces](https://github.com/features/codespaces).
- Full support for [Microsoft SQL storage provider](https://github.com/microsoft/durabletask-mssql).
- Latest [az-func-as-a-graph](https://github.com/scale-tone/az-func-as-a-graph) integrated.
- Minor bugfixes.
## Version 4.7.1
- Hotfix for incompatibility with Storage Emulator ([#112](https://github.com/scale-tone/DurableFunctionsMonitor/issues/112)).
## Version 4.7
- Latest [az-func-as-a-graph](https://github.com/scale-tone/az-func-as-a-graph) integrated, and it is now used as yet another visualization tab for both search results and instance details, with instance counts and statuses rendered on top of it. So it now acts as an *animated* code map of your project:

- 'Open XXXInstances/XXXHistory in Storage Explorer' menu items for Task Hubs:
- Long JSON (or just long error messages) can now be viewed in a popup window ([#109](https://github.com/scale-tone/DurableFunctionsMonitor/issues/109)).
- Minor bugfixes.
## Version 4.6
- Added a sortable **Duration** column to the list of results. Now you can quickly find quickest and longest instances.
- Gantt charts are now interactive (lines are clickable).
- Custom backends: you can now switch to a .Net Core 3.1 backend, or even to your own customized one:

- (Limited) support for [Microsoft SQL storage provider](https://github.com/microsoft/durabletask-mssql). When you open a project that uses it, the relevant Task Hub should appear in the **DURABLE FUNCTIONS** view container:

- Minor bugfixes.
## Version 4.5
- Time can now be shown in local time zone. **File->Preferences->Settings->Durable Functions Monitor->Show Time As**.
- F# support for Functions Graphs.
- Instance Details tab is now integrated with Functions Graph. If relevant Functions project is currently open, the Details tab will allow navigating to Functions Graph and to Orchestration/Entity/Activity source code.
- Minor bugfixes.
## Version 4.4
- Now you can get a quick overview of _any_ Azure Functions project in form of a graph. **Command Palette -> Visualize Functions as a Graph...**. For Durable Functions/Durable Entities the tool also tries to infer and show their relationships. Function nodes are clickable and lead to function's code.
- Minor bugfixes.
## Version 4.3
- Fixed time ranges ('Last Minute', 'Last Hour' etc.).
- Multiple choice for filtering by instance status ('Running', 'Completed' etc.).
- 'Not Equals', 'Not Starts With' and 'Not Contains' filter operators.
- Performance improvements.
- Minor bugfixes.
## Version 4.2
- Orchestrations/Entities are now also visualized as a time histogram and as a Gantt chart. Time histogram is interactive, you can zoom it in/out with your mouse.
- 'Send Signal' button for Durable Entities.
- Minor bugfixes.
## Version 4.1
- Dark color mode.
- Minor bugfixes.
## Version 4.0
- It is now one backend per Storage Account, not per each Task Hub. Works faster and consumes less resources.
- Minor bugfixes.
## Version 3.9
- Gantt Charts for orchestrations (in addition to Sequence Diagrams).
- 'Go to instanceId...' feature to quickly navigate to an orchestration/entity instance by its id (with autocomplete supported). **Right-click on a Task Hub->Go to instanceId...**.
- DotLiquid replaced with [Fluid](https://github.com/sebastienros/fluid) for rendering custom status tabs. [Fluid](https://github.com/sebastienros/fluid) looks much more mature (most of [Liquid](https://shopify.github.io/liquid/) seems to be supported) and more alive library.
- 'Save as .SVG' button for diagrams.
- Status tabs now refresh much smoother.
- Minor bugfixes.
## Version 3.8
- WebViews are now persistent (do not reload every time you switch between them) and even persist their state (filters, sorting etc.) across restarts.
- 'Restart' button for orchestrations (triggers the new [.RestartAsync()](https://github.com/Azure/azure-functions-durable-extension/pull/1545) method).
- Sequence diagrams now show some timing (start times and durations).
- 'Detach from all Task Hubs...' button for quickly killing all backends.
- All logs (when enabled) now go to 'Durable Functions Monitor' output channel.
- Minor bugfixes.
## Version 3.7
- Now settings are stored in VsCode's settings.json. **File->Preferences->Settings->Durable Functions Monitor**:
- Local Storage Emulator, Azure Government and other exotic Storage Account types are now supported. If your Local Storage Emulator is running and there're some TaskHubs in it - they will appear automatically on your Azure Functions View Container (if not, try to modify the 'Storage Emulator Connection String' parameter on the Settings page).
- Long-awaited 'Cancel' button on the Orchestrations page.
- Now you can hide the columns you're not interested in:
- Minor other UI improvements.
## Version 3.6
- 'Clear Entity Storage...' menu item for doing garbage collection of deleted Durable Entities. Executes the recently added [IDurableEntityClient.CleanEntityStorageAsync()](https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.webjobs.extensions.durabletask.idurableentityclient.cleanentitystorageasync?view=azure-dotnet) method.
- Custom status visualisation for orchestrations/entities in form of [Liquid templates](https://shopify.github.io/liquid/).
1. Create a [DotLiquid](https://github.com/dotliquid/dotliquid) template file.
2. Name it like `[My Custom Tab Name].[orchestration-or-entity-name].liquid` or just `[My Custom Tab Name].liquid` (this one will be applied to any kind of entity).
3. In the same Storage Account create a container called `durable-functions-monitor`.
4. Put your template file into a `tab-templates` virtual folder in that container (the full path should look like `/durable-functions-monitor/tab-templates/[My Custom Tab Name].[orchestration-or-entity-name].liquid`).
5. Restart Durable Functions Monitor.
6. Observe the newly appeared `My Custom Tab Name` tab on the Orchestration/Entity Details page.
- Performance improvements for loading the list of Orchestrations/Entities.
## Version 3.5
- Now the **Orchestration Details** page features a nice [mermaid](https://www.npmjs.com/package/mermaid)-based sequence diagram:
- Also it's now possible to navigate to suborchestrations from the history list on the **Orchestration Details** page.
## Version 3.4
- Now integrated with [Azure Account](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azure-account) extension, so once logged in to Azure, you can now see and connect to all your TaskHubs. It is also still possible to connect with connection strings, as before. NOTE1: only filtered Azure Subscriptions are shown, so make sure your filter is set correctly with [Azure: Select Subscriptions](https://docs.microsoft.com/en-us/azure/governance/policy/how-to/extension-for-vscode#select-subscriptions) command. NOTE2: many things can go wrong when fetching the list of TaskHubs, so to investigate those problems you can [enable logging](https://github.com/scale-tone/DurableFunctionsMonitor/blob/master/durablefunctionsmonitor-vscodeext/CHANGELOG.md#version-21) and then check the 'Durable Functions Monitor' output channel.
## Version 3.3
- customStatus value of your orchestration instances can now be changed with 'Set Custom Status' button.
- Minor bugfixes.
## Version 3.2
- You can now delete unused Task Hubs with 'Delete Task Hub...' context menu item.
- Better (non-native) DateTime pickers.
## Version 3.1
- Minor security improvements.
- List of existing Task Hubs is now loaded from your Storage Account and shown to you, when connecting to a Task Hub.
## Version 3.0
- A 'DURABLE FUNCTIONS' TreeView added to Azure Functions View Container. It displays all currently attached Task Hubs, allows to connect to multiple Task Hubs and switch between them. You need to have [Azure Functions](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions) extension installed to see it (which is typically the case if you work with Azure Functions in VSCode).
## Version 2.2
- Bulk purge for Durable Entities as well.
- Prettified JSON on instance details page.
## Version 2.1
- Instances list sort order is now persisted as well.
- Whenever backend initialization fails, its error message is now being shown immediately (instead of a generic 'timeout' message as before).
- A complete backend output can now be logged into a file for debugging purposes. Open the **settings.json** file in extension's folder and set the **logging** setting to **true**. That will produce a **backend/backend-37072.log** file with full console output from func.exe.
## Version 2.0
- More native support for Durable Entities.
- Backend migrated to Microsoft.Azure.WebJobs.Extensions.DurableTask 2.0.0. Please, ensure you have the latest Azure Functions Core Tools installed globally, otherwise the backend might fail to start.
- Now displaying connection info (storage account name/hub name) in the tab title.
## Version 1.3
- Implemented purging orchestration instance history. Type 'Purge Durable Functions History...' in your Command Palette.
- Added a context menu over a **host.json** file.
================================================
FILE: durablefunctionsmonitor-vscodeext/LICENSE
================================================
MIT License
Copyright (c) 2019 scale-tone
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: durablefunctionsmonitor-vscodeext/README.md
================================================
# Durable Functions Monitor as a VsCode Extension
List/monitor/debug your Azure Durable Functions inside VsCode.
**Command Palette -> Durable Functions Monitor**, or (if you have [Azure Functions](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions) extension also installed) **Azure Functions View Container -> DURABLE FUNCTIONS**, or right-click on your **host.json** file and use the context menu.
## Features
* Get a bird's eye view of any Azure Functions project in form of a graph - **Command Palette -> Visualize Functions as a Graph...**.
* List your Orchestrations and/or Durable Entities, with sorting, infinite scrolling and auto-refresh.
* Monitor the status of a certain Orchestration/Durable Entity. Restart, Purge, Rewind, Terminate, Raise Events.
* Start new orchestration instances - **Azure Functions View Container -> DURABLE FUNCTIONS -> [right-click on your TaskHub] -> Start New Orchestration Instance...**
* Quickly navigate to an Orchestration/Entity instance by its ID - **Command Palette -> Durable Functions Monitor: Go to instanceId...** or **Azure Functions View Container -> DURABLE FUNCTIONS -> [right-click on your TaskHub] -> Go to instanceId...**
* Purge Orchestrations/Durable Entities history - **Command Palette -> Durable Functions Monitor: Purge History...**
* Cleanup deleted Durable Entities - **Command Palette -> Durable Functions Monitor: Clean Entity Storage...**
* Observe all Task Hubs in your Azure Subscription and connect to them - **Azure Functions View Container -> DURABLE FUNCTIONS**
* Delete Task Hubs - **Command Palette -> Delete Task Hub...**
## Pictures
## Prerequisites
Make sure you have the latest [Azure Functions Core Tools](https://www.npmjs.com/package/azure-functions-core-tools) globally installed on your devbox.
More info and sources on [the github repo](https://github.com/scale-tone/DurableFunctionsMonitor#features).
================================================
FILE: durablefunctionsmonitor-vscodeext/package.json
================================================
{
"name": "durablefunctionsmonitor",
"displayName": "Durable Functions Monitor",
"description": "Monitoring/debugging UI tool for Azure Durable Functions. View->Command Palette...->Durable Functions Monitor",
"version": "5.1.0",
"engines": {
"vscode": "^1.39.0"
},
"categories": [
"Other",
"Debuggers"
],
"homepage": "https://github.com/scale-tone/DurableFunctionsMonitor",
"repository": {
"type": "git",
"url": "https://github.com/scale-tone/DurableFunctionsMonitor"
},
"bugs": {
"url": "https://github.com/scale-tone/DurableFunctionsMonitor/issues"
},
"icon": "logo.png",
"keywords": [
"Azure Durable Functions",
"Azure Durable Entities",
"Azure Functions",
"Serverless",
"Azure"
],
"publisher": "DurableFunctionsMonitor",
"license": "MIT",
"activationEvents": [
"onView:durableFunctionsMonitorTreeView",
"onCommand:extension.durableFunctionsMonitor",
"onCommand:extension.durableFunctionsMonitorPurgeHistory",
"onCommand:extension.durableFunctionsMonitorCleanEntityStorage",
"onCommand:durableFunctionsMonitorTreeView.attachToAnotherTaskHub",
"onCommand:extension.durableFunctionsMonitorGotoInstanceId",
"onCommand:extension.durableFunctionsMonitorVisualizeAsGraph",
"onCommand:durableFunctionsMonitorTreeView.startNewInstance",
"onDebug"
],
"main": "./out/extension.js",
"contributes": {
"views": {
"azure": [
{
"id": "durableFunctionsMonitorTreeView",
"name": "Durable Functions"
}
]
},
"commands": [
{
"command": "extension.durableFunctionsMonitor",
"title": "Durable Functions Monitor"
},
{
"command": "extension.durableFunctionsMonitorPurgeHistory",
"title": "Durable Functions Monitor: Purge History..."
},
{
"command": "extension.durableFunctionsMonitorCleanEntityStorage",
"title": "Durable Functions Monitor: Clean Entity Storage..."
},
{
"command": "extension.durableFunctionsMonitorGotoInstanceId",
"title": "Durable Functions Monitor: Go to instanceId..."
},
{
"command": "extension.durableFunctionsMonitorVisualizeAsGraph",
"title": "Visualize Functions as a Graph..."
},
{
"command": "durableFunctionsMonitorTreeView.attachToTaskHub",
"title": "Attach"
},
{
"command": "durableFunctionsMonitorTreeView.detachFromTaskHub",
"title": "Detach"
},
{
"command": "durableFunctionsMonitorTreeView.openInstancesInStorageExplorer",
"title": "Open *Instances table in Storage Explorer"
},
{
"command": "durableFunctionsMonitorTreeView.openHistoryInStorageExplorer",
"title": "Open *History table in Storage Explorer"
},
{
"command": "durableFunctionsMonitorTreeView.deleteTaskHub",
"title": "Delete Task Hub..."
},
{
"command": "durableFunctionsMonitorTreeView.refresh",
"title": "Refresh",
"icon": {
"light": "resources/light/refresh.svg",
"dark": "resources/dark/refresh.svg"
}
},
{
"command": "durableFunctionsMonitorTreeView.attachToAnotherTaskHub",
"title": "Attach to Task Hub...",
"icon": {
"light": "resources/light/plug.svg",
"dark": "resources/dark/plug.svg"
}
},
{
"command": "durableFunctionsMonitorTreeView.detachFromAllTaskHubs",
"title": "Detach from all Task Hubs...",
"icon": {
"light": "resources/light/unplug.svg",
"dark": "resources/dark/unplug.svg"
}
},
{
"command": "durableFunctionsMonitorTreeView.purgeHistory",
"title": "Purge History..."
},
{
"command": "durableFunctionsMonitorTreeView.cleanEntityStorage",
"title": "Clean Entity Storage..."
},
{
"command": "durableFunctionsMonitorTreeView.gotoInstanceId",
"title": "Go to instanceId..."
},
{
"command": "durableFunctionsMonitorTreeView.startNewInstance",
"title": "Start New Orchestration Instance..."
}
],
"menus": {
"explorer/context": [
{
"command": "extension.durableFunctionsMonitor",
"when": "resourceFilename == host.json",
"group": "DurableFunctionMonitorGroup@1"
},
{
"command": "extension.durableFunctionsMonitorPurgeHistory",
"when": "resourceFilename == host.json",
"group": "DurableFunctionMonitorGroup@2"
},
{
"command": "extension.durableFunctionsMonitorCleanEntityStorage",
"when": "resourceFilename == host.json",
"group": "DurableFunctionMonitorGroup@3"
},
{
"command": "extension.durableFunctionsMonitorGotoInstanceId",
"when": "resourceFilename == host.json",
"group": "DurableFunctionMonitorGroup@4"
},
{
"command": "extension.durableFunctionsMonitorVisualizeAsGraph",
"when": "resourceFilename == host.json",
"group": "DurableFunctionMonitorGroup@5"
}
],
"view/title": [
{
"command": "durableFunctionsMonitorTreeView.refresh",
"when": "view == durableFunctionsMonitorTreeView",
"group": "navigation@1"
},
{
"command": "durableFunctionsMonitorTreeView.detachFromAllTaskHubs",
"when": "view == durableFunctionsMonitorTreeView",
"group": "navigation@2"
},
{
"command": "durableFunctionsMonitorTreeView.attachToAnotherTaskHub",
"when": "view == durableFunctionsMonitorTreeView",
"group": "navigation@3"
}
],
"view/item/context": [
{
"command": "durableFunctionsMonitorTreeView.gotoInstanceId",
"when": "view == durableFunctionsMonitorTreeView && viewItem == taskHub-attached",
"group": "2_purge_history@3"
},
{
"command": "durableFunctionsMonitorTreeView.cleanEntityStorage",
"when": "view == durableFunctionsMonitorTreeView && viewItem == taskHub-attached",
"group": "2_purge_history@2"
},
{
"command": "durableFunctionsMonitorTreeView.purgeHistory",
"when": "view == durableFunctionsMonitorTreeView && viewItem == taskHub-attached",
"group": "2_purge_history@1"
},
{
"command": "durableFunctionsMonitorTreeView.startNewInstance",
"when": "view == durableFunctionsMonitorTreeView && viewItem == taskHub-attached",
"group": "2_purge_history@0"
},
{
"command": "durableFunctionsMonitorTreeView.deleteTaskHub",
"when": "view == durableFunctionsMonitorTreeView && viewItem == taskHub-attached",
"group": "3_delete_task_hub@1"
},
{
"command": "durableFunctionsMonitorTreeView.attachToTaskHub",
"when": "view == durableFunctionsMonitorTreeView && viewItem == taskHub-detached",
"group": "1_attach_detach@1"
},
{
"command": "durableFunctionsMonitorTreeView.detachFromTaskHub",
"when": "view == durableFunctionsMonitorTreeView && viewItem == storageAccount-attached"
},
{
"command": "durableFunctionsMonitorTreeView.openInstancesInStorageExplorer",
"when": "view == durableFunctionsMonitorTreeView && viewItem == taskHub-attached || viewItem == taskHub-detached",
"group": "4_storage_explorer@1"
},
{
"command": "durableFunctionsMonitorTreeView.openHistoryInStorageExplorer",
"when": "view == durableFunctionsMonitorTreeView && viewItem == taskHub-attached || viewItem == taskHub-detached",
"group": "4_storage_explorer@2"
}
],
"commandPalette": [
{
"command": "durableFunctionsMonitorTreeView.openInstancesInStorageExplorer",
"when": "never"
},
{
"command": "durableFunctionsMonitorTreeView.openHistoryInStorageExplorer",
"when": "never"
}
]
},
"configuration": {
"title": "Durable Functions Monitor",
"properties": {
"durableFunctionsMonitor.backendBaseUrl": {
"type": "string",
"default": "http://localhost:{portNr}/a/p/i",
"description": "URL the backend(s) to be started on. You might want e.g. to change 'localhost' to '127.0.0.1', if you're observing firewall issues. Also it is possible to lock the port number here, if needed (by default it is automatically chosen from the range 37072-38000)."
},
"durableFunctionsMonitor.backendVersionToUse": {
"type": "string",
"enum": [
"Default",
".Net Core 3.1",
".Net Core 2.1"
],
"default": "Default",
"description": "Choose which backend binaries to use when starting a backend. Currently 'Default' backend targets .Net Core 2.1, but you can try other ones, if 'Default' doesn't work for you."
},
"durableFunctionsMonitor.customPathToBackendBinaries": {
"type": "string",
"description": "Put local path to a custom backend implementation to use. Overrides 'Backend Version to Use' when set."
},
"durableFunctionsMonitor.backendTimeoutInSeconds": {
"type": "number",
"default": "60",
"description": "Number of seconds to wait for the backend to start."
},
"durableFunctionsMonitor.storageEmulatorConnectionString": {
"type": "string",
"default": "AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;",
"description": "Connection String to talk to local Storage Emulator. The AccountKey here is a well-known AccountKey. Customize endpoint URLs when needed."
},
"durableFunctionsMonitor.enableLogging": {
"type": "boolean",
"default": false,
"description": "Enable extensive logging and output logs into 'Durable Functions Monitor' output channel"
},
"durableFunctionsMonitor.showTimeAs": {
"type": "string",
"default": "UTC",
"enum": [
"UTC",
"Local"
],
"description": "In which time zone time values should be displayed"
},
"durableFunctionsMonitor.showWhenDebugSessionStarts": {
"type": "boolean",
"default": false,
"description": "Show Durable Functions Monitor when you start debugging a Durable Functions project"
}
}
}
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"pretest": "npm run compile",
"test": "node ./out/test/runTest.js",
"package": "node ./node_modules/vsce/out/vsce package"
},
"devDependencies": {
"@types/glob": "^7.1.1",
"@types/mocha": "^5.2.6",
"@types/node": "^10.12.21",
"@types/vscode": "^1.39.0",
"glob": "^7.1.4",
"mocha": "^8.2.0",
"tslint": "^5.12.1",
"typescript": "^3.3.1",
"vsce": "^1.88.0",
"vscode-test": "^1.2.0"
},
"dependencies": {
"@azure/arm-storage": "^15.1.0",
"@types/crypto-js": "^3.1.47",
"@types/rimraf": "^3.0.0",
"rimraf": "^3.0.2",
"axios": "^0.21.2",
"crypto-js": "^4.0.0",
"portscanner": "^2.2.0",
"tree-kill": "^1.2.2"
},
"extensionDependencies": [
"ms-vscode.azure-account"
]
}
================================================
FILE: durablefunctionsmonitor-vscodeext/src/BackendProcess.ts
================================================
const portscanner = require('portscanner');
import * as fs from 'fs';
import * as path from 'path';
import * as vscode from 'vscode';
import * as crypto from 'crypto';
import * as killProcessTree from 'tree-kill';
import axios from 'axios';
import { spawn, spawnSync, ChildProcess } from 'child_process';
import * as CryptoJS from 'crypto-js';
import { ConnStringUtils } from "./ConnStringUtils";
import * as SharedConstants from './SharedConstants';
import { Settings } from './Settings';
// Responsible for running the backend process
export class BackendProcess {
constructor(private _binariesFolder: string,
private _storageConnectionSettings: StorageConnectionSettings,
private _removeMyselfFromList: () => void,
private _log: (l: string) => void)
{ }
// Underlying Storage Connection Strings
get storageConnectionStrings(): string[] {
return this._storageConnectionSettings.storageConnStrings;
}
// Information about the started backend (if it was successfully started)
get backendUrl(): string {
return this._backendUrl;
}
// Folder where backend is run from (might be different, if the backend needs to be published first)
get binariesFolder(): string {
return this._eventualBinariesFolder;
}
// Kills the pending backend process
cleanup(): Promise