Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add app insights monitoring #151

Merged
merged 18 commits into from
Oct 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
ADO_PAT=(PAT from Azure DevOps)
ADO_URL=(https://dev.azure.com/ORG)
APPLICATIONINSIGHTS_CONNECTION_STRING=(Connection string from Azure Application Insights, or blank if not using)
ASANA_TOKEN=(PAT from Asana)
ASANA_WORKSPACE_NAME=(Name of the Asana Workspace)
OTEL_SERVICE_NAME=sync
danstis marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"justMyCode": true,
"envFile": "${workspaceFolder}/.env",
"env": {
"LOG_LEVEL": "DEBUG",
"LOG_LEVEL": "INFO"
}
}
]
}
}
29 changes: 22 additions & 7 deletions ado_asana_sync/sync/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@

import logging
import os
from typing import Optional

import asana # type: ignore
from azure.devops.connection import Connection # type: ignore
from azure.monitor.opentelemetry import configure_azure_monitor
from msrest.authentication import BasicAuthentication
from tinydb import TinyDB

Expand Down Expand Up @@ -57,13 +59,22 @@ def __init__(
ado_url: str = "",
asana_token: str = "",
asana_workspace_name: str = "",
applicationinsights_connection_string: Optional[str] = None,
) -> None:
self.ado_pat = ado_pat or os.environ.get("ADO_PAT")
self.ado_url = ado_url or os.environ.get("ADO_URL")
self.asana_token = asana_token or os.environ.get("ASANA_TOKEN")
self.ado_pat = ado_pat or os.environ.get("ADO_PAT", "")
self.ado_url = ado_url or os.environ.get("ADO_URL", "")
self.asana_token = asana_token or os.environ.get("ASANA_TOKEN", "")
self.asana_workspace_name = asana_workspace_name or os.environ.get(
"ASANA_WORKSPACE_NAME"
"ASANA_WORKSPACE_NAME", ""
)
self.applicationinsights_connection_string = (
applicationinsights_connection_string
or os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING", None)
)
if not self.applicationinsights_connection_string:
os.environ["OTEL_LOGS_EXPORTER"] = "None"
os.environ["OTEL_METRICS_EXPORTER"] = "None"
os.environ["OTEL_TRACES_EXPORTER"] = "None"
danstis marked this conversation as resolved.
Show resolved Hide resolved
self.ado_core_client = None
self.ado_wit_client = None
self.ado_work_client = None
Expand Down Expand Up @@ -97,19 +108,23 @@ def connect(self) -> None:
"""
Connects to ADO and Asana, and sets up the TinyDB database.
"""
# connect ADO
# Connect ADO.
_LOGGER.debug("Connecting to Azure DevOps")
ado_credentials = BasicAuthentication("", self.ado_pat)
ado_connection = Connection(base_url=self.ado_url, creds=ado_credentials)
self.ado_core_client = ado_connection.clients.get_core_client()
self.ado_work_client = ado_connection.clients.get_work_client()
self.ado_wit_client = ado_connection.clients.get_work_item_tracking_client()
# connect Asana
# Connect Asana.
_LOGGER.debug("Connecting to Asana")
asana_config = asana.Configuration()
asana_config.access_token = self.asana_token
self.asana_client = asana.ApiClient(asana_config)
# setup tinydb
# Configure application insights.
configure_azure_monitor(
connection_string=self.applicationinsights_connection_string,
)
# Setup tinydb.
_LOGGER.debug("Opening local database")
self.db = TinyDB(
os.path.join(os.path.dirname(__package__), "data", "appdata.json")
danstis marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
72 changes: 39 additions & 33 deletions ado_asana_sync/sync/asana.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@

from __future__ import annotations

import logging

import asana # type: ignore
from asana.rest import ApiException # type: ignore

from .app import App
from ado_asana_sync.utils.logging_tracing import setup_logging_and_tracing

from .app import App

# _LOGGER is the logging instance for this file.
_LOGGER = logging.getLogger(__name__)
# This module uses the logger and tracer instances _LOGGER and _TRACER for logging and tracing, respectively.
_LOGGER, _TRACER = setup_logging_and_tracing(__name__)


def get_asana_task(app: App, task_gid: str) -> object | None:
Expand All @@ -26,32 +25,39 @@ def get_asana_task(app: App, task_gid: str) -> object | None:
:return: Task object or None if no task is found.
:rtype: object or None
"""
api_instance = asana.TasksApi(app.asana_client)
try:
# Get all tasks in the project.
opt_fields = [
"assignee_section",
"due_at",
"name",
"completed_at",
"tags",
"dependents",
"projects",
"completed",
"permalink_url",
"parent",
"assignee",
"assignee_status",
"num_subtasks",
"modified_at",
"workspace",
"due_on",
]
api_response = api_instance.get_task(
task_gid,
opt_fields=opt_fields,
with _TRACER.start_as_current_span("get_asana_task") as span:
span.set_attributes(
{
"asana_workspace_name": app.asana_workspace_name,
"task_gid": task_gid,
}
)
return api_response.data
except ApiException as exception:
_LOGGER.error("Exception when calling TasksApi->get_task: %s\n", exception)
return None
api_instance = asana.TasksApi(app.asana_client)
try:
# Get all tasks in the project.
opt_fields = [
"assignee_section",
"due_at",
"name",
"completed_at",
"tags",
"dependents",
"projects",
"completed",
"permalink_url",
"parent",
"assignee",
"assignee_status",
"num_subtasks",
"modified_at",
"workspace",
"due_on",
]
api_response = api_instance.get_task(
task_gid,
opt_fields=opt_fields,
)
return api_response.data
except ApiException as exception:
_LOGGER.error("Exception when calling TasksApi->get_task: %s\n", exception)
return None
danstis marked this conversation as resolved.
Show resolved Hide resolved
Loading
Loading