Application Insights API for custom metrics multiple dimensions - azure-application-insights

I have the following code Application Insights API for custom events (https://learn.microsoft.com/en-us/azure/azure-monitor/app/api-custom-events-metrics#get-a-telemetryclient-instance):
private void TrackResourceUnitsUsedByTypeEvent(int ruu, QueryType queryType)
{
var ruuByTypeEvent = new Dictionary<string, string>
{
{ "RunId", RunId.ToString() },
{ "ResourceUnitsUsed", ruu.ToString() },
{ "QueryType", queryType.ToString() }
};
_telemetryClient.TrackEvent("ResourceUnitsUsed", ruuByTypeEvent);
}
and the following kusto query:
customEvents
| where name == "ResourceUnitsUsed"
| order by timestamp desc
| project timestamp,
QueryType = tostring(customDimensions["QueryType"]),
ResourceUnitsUsed = toint(customDimensions["ResourceUnitsUsed"])
| summarize sum(ResourceUnitsUsed) by bin(timestamp, 1m), QueryType
How do I update the code to display custom metric instead of custom event?

Just change TrackEvent to TrackMetric. With this you don't need to pass a value as custom property - instead you pass it directly. This simplifies (and makes it faster) Kusto query as well.
Here is how you can modify it:
private void TrackResourceUnitsUsedByTypeMetric(int ruu, QueryType queryType)
{
var ruuByTypeProperties = new Dictionary<string, string>
{
{ "RunId", RunId.ToString() },
{ "QueryType", queryType.ToString() }
};
_telemetryClient.TrackMetric("ResourceUnitsUsed", ruu, ruuByTypeProperties);
}
And query:
customMetrics
| where name == "ResourceUnitsUsed"
| order by timestamp desc
| project timestamp,
QueryType = tostring(customDimensions["QueryType"]),
ResourceUnitsUsed = toint(value)
| summarize sum(ResourceUnitsUsed) by bin(timestamp, 1m), QueryType

Related

Prisma why is UpdateInput schema different than my table schema?

i'm having trouble when updating one table.
I'm using NextJS
I have these 2 models. The property bank of bank_data_users creates a relation with banks model
model bank_data_users {
id Int #id #default(autoincrement()) #db.UnsignedInt
fullName String? #db.VarChar(255)
userPermissions Int?
bank Int?
bankInfo banks? #relation(fields: [bank], references: [id])
userPermissionsRef users? #relation(fields: [userPermissions], references: [id])
}
model banks {
id Int #id #default(autoincrement()) #db.UnsignedInt
code String? #db.VarChar(255)
bank bank_data_users[]
}
When i try to update it, i get this error
Unknown arg `bank` in data.bank for type bank_data_usersUpdateInput. Did you mean `type`? Available args:
type bank_data_usersUpdateInput {
fullName?: String | NullableStringFieldUpdateOperationsInput | Null
type?: String | NullableStringFieldUpdateOperationsInput | Null
bankInfo?: banksUpdateOneWithoutBankNestedInput
userPermissionsRef?: usersUpdateOneWithoutBankNestedInput
}
So i accessed the index.d.ts that's located at node_modules\.prisma\client\index.d.ts to see the type bank_data_usersUpdateInput. It looks like this
export type bank_data_usersUpdateInput = {
fullName?: NullableStringFieldUpdateOperationsInput | string | null
type?: NullableStringFieldUpdateOperationsInput | string | null
bankInfo?: banksUpdateOneWithoutBankNestedInput
userPermissionsRef?: usersUpdateOneWithoutBankNestedInput
}
Why doesn't it have the bank and userPermissions property?
I'm updating it like this
const id = Number(req.query.id);
await prisma.bank_data_users.update({
where: { id },
data: {bank:body.bank},
});

Quatz.Net GetNextFireTime() returning the "wrong timezone"

I am currently working on a project in which I am using the Quartz Scheduler.
I've been working on a feature that displays different details about jobs that are currently active, using the following method.
public IEnumerable<ActiveScheduleJob> GetAllActiveScheduls()
{
var activeScheduls = new List<ActiveScheduleJob>();
try
{
IList<string> jobGroups = scheduler.GetJobGroupNames();
// IList<string> triggerGroups = scheduler.GetTriggerGroupNames();
ActiveScheduleJob ASJ;
foreach (string group in jobGroups)
{
var groupMatcher = GroupMatcher<JobKey>.GroupContains(group);
var jobKeys = scheduler.GetJobKeys(groupMatcher);
foreach (var jobKey in jobKeys)
{
var detail = scheduler.GetJobDetail(jobKey);
var triggers = scheduler.GetTriggersOfJob(jobKey);
foreach (ITrigger trigger in triggers)
{
ASJ = new ActiveScheduleJob();
ASJ.Group = group;
ASJ.Name = jobKey.Name;
ASJ.Description = detail.Description;
ASJ.TriggerKeyName = trigger.Key.Name;
ASJ.TriggerKeyGroup = trigger.Key.Group;
ASJ.TriggerGetTypeName = trigger.GetType().Name;
ASJ.TriggerState = scheduler.GetTriggerState(trigger.Key);
ASJ.NextFireTime = trigger.GetNextFireTimeUtc();
if (ASJ.NextFireTime.HasValue)
{
ASJ.NextFireTimeString = ASJ.NextFireTime.Value.LocalDateTime.ToString();
}
ASJ.PreviousFireTime = trigger.GetPreviousFireTimeUtc();
if (ASJ.PreviousFireTime.HasValue)
{
ASJ.PreviousFireTimeString = ASJ.PreviousFireTime.Value.LocalDateTime.ToString();
}
ASJ.FullJobString = $"Trigger Name: {ASJ.TriggerKeyName} | Trigger Group: {ASJ.TriggerKeyGroup} | Trigger State: {ASJ.TriggerState} | Trigger Get Type: {ASJ.TriggerGetTypeName} | Job Name: {ASJ.Name} | Job Group: {ASJ.Group} | Next Fire Time: {ASJ.NextFireTimeString} | Previous Fire Time: {ASJ.PreviousFireTimeString} | Description: {ASJ.Description}";
activeScheduls.Add(ASJ);
}
}
}
}
catch (Exception ex)
{
logging.WriteLog(1, "JobScheduler", "GetAllActiveScheduls", "Hent alle aktive job+triggers", $"EXCEPTION MESSAGE: {ex.Message} | EXCEPTION INNER: {ex.InnerException}", LogType.Exception, "");
}
return activeScheduls;
}
The method in it self works just fine, my problems lies in the fact that the GetNextFireTime() method, gives it in UTC which is an hour behind my GMT+1 / UTC+1.
When it displays: 10-01-2018 07:00:00 +00:00
It should display: 10-01-2018 08:00:00 +01:00
I've looked at the following link: Working With DateTimeOffset
and tried to work with what Marko Lahma mentioned could work in converting the DateTimeOffset. But I've run into a wall where I can't convert it, because GetNextFireTime() returns a DataTimeOffset? and what I've tried, can't convert something thats Nullable. So I am abit stumped in what to do
You can convert the DateTimeOffset to a local DateTimeOffset and that to a DateTime.
var nextFireDateTime = trigger.GetNextFireTimeUtc()?.ToLocalTime().DateTime;
Please note that nextFireDateTime could be null.

Adding attachments to task records in T_SQL

I have an application which stores tasks and I want to add attachments to those tasks.
I have tried three different ways of doing this and don't know if any of them are correct and am looking for advice on where to go:
For example, simplified I have used a table:
+----------------------------------------------------------------------------+
| TaskID Description attachmentString |
+----------------------------------------------------------------------------+
| 1 Task1 "FileName1:::fileLocation;FileName2:::fileLocation" |
| 2 Task2 "FileName3:::fileLocation;FileName4:::fileLocation" |
+----------------------------------------------------------------------------+
This is similar to how profile data is stored in ASP.NET membership.
I have also tried:
+---------------------------+
| TaskID Description |
+---------------------------+
| 1 Task1 |
| 2 Task2 |
+---------------------------+
+------------------------------------------------------+
| AttachmentId Description Location TaskId |
+------------------------------------------------------+
| 1 FileName1 FileLocation 1 |
| 2 FileName2 FileLocation 1 |
+------------------------------------------------------+
If I use the first option, I can just select tasks and get all the attachment data in one SQL call; but it seems cluncky to me to have to then parse the string. Its also not very "relational"
However using an attachment Id, if I want to get the attachments, I either JOIN both tables on attachmentId and then have number of attachments x number of tasks returned. I can have up to 5 attachments so for 50 tasks, it could return 250 rows of which the first columns (from the task table side of the JOIN) are repeated and this seems like a waste. Obviously I have a little more than just description in my table!!!
I have also considered just getting the task data and then just getting the attachment data separately and then joining them in my application. This returns less data than the second option, but requires two calls to the database and that seems wrong too.
I am doing this wrong? Is there a better way? Does anyone have any thoughts on the best way to do this.
I'm not very confident with SQL and maybe I have missed something huge so any pointers would be gratefully received.
The right design is obviously two tables. Having only one table violates the first normal form.
Relating to the load problem, both approaches are correct.
Joining the tables in the sql statement is what most ORM's do to eagerly load related objects. Obviously there is some network traffic overhead, but I think it is acceptable.
Executing two separate sql statements is also correct. You can send them together in one batch to SQL Server to save roundtrips. It has a disadvantage although, you need to perform the join at the client side.
So, are you willing to write more code to save some network traffic?
EDIT:
Given the following table and data:
CREATE TABLE Tasks
(
TaskId int IDENTITY(1,1) PRIMARY KEY,
TaskDescription nvarchar(500) NOT NULL
)
CREATE TABLE TaskAttachments
(
AttachmentId int IDENTITY(1,1) PRIMARY KEY,
TaskId int NOT NULL REFERENCES Tasks(TaskId),
[FileName] nvarchar(500) NOT NULL,
[FileLocation] nvarchar(500) NOT NULL
)
GO
INSERT INTO Tasks VALUES
('Task1'), ('Task2')
INSERT INTO TaskAttachments VALUES
(1, 'FileName1', 'File location 1'),
(1, 'Filename2', 'File location 2'),
(2, 'FileName3', 'File location 3'),
(2, 'Filename4', 'File location 4')
The following classes:
public class TaskAttachment
{
public int AttachmentId { get; set; }
public string FileName { get; set; }
public string FileLocation { get; set; }
}
public class AppTask
{
public int TaskId { get; set; }
public string TaskDescription { get; set; }
public List<TaskAttachment> Attachments { get; set; }
public AppTask()
{
this.Attachments = new List<TaskAttachment>();
}
}
The following class loads the tasks with its attachments by executing two select statements in one single batch:
public class DataLayer
{
private readonly SqlConnection connection;
public DataLayer(SqlConnection connection)
{
this.connection = connection;
}
public List<AppTask> GetTasks()
{
var commandText = #"
SELECT TaskId, TaskDescription FROM Tasks;
SELECT AttachmentId, TaskId, [FileName], FileLocation FROM TaskAttachments;
";
using (var cmd = new SqlCommand(commandText, connection))
using (var reader = cmd.ExecuteReader())
{
var tasks = new List<AppTask>();
while (reader.Read())
{
var task = new AppTask
{
TaskId = reader.GetInt32(0),
TaskDescription = reader.GetString(1)
};
tasks.Add(task);
}
var taskDic = tasks.ToDictionary(x => x.TaskId);
reader.NextResult();
while (reader.Read())
{
var attachment = new TaskAttachment
{
AttachmentId = reader.GetInt32(0),
TaskId = reader.GetInt32(1),
FileName = reader.GetString(2),
FileLocation = reader.GetString(3)
};
var task = taskDic[attachment.TaskId];
task.Attachments.Add(attachment);
}
return tasks;
}
}
}
You can use the above class like this:
using (var cn = new SqlConnection("Data Source=(local);Initial Catalog=Tests;Integrated Security=SSPI"))
{
var dataLayer = new DataLayer(cn);
cn.Open();
var tasks = dataLayer.GetTasks();
}

Left join using a different or not equal in Entity Framework

I have to build a query to get users that did not received and alert about new posts.
My relevant table structure is as follows:
Posts: postId int
Users: userId int, email varchar
PostAlertUsers: postAlertUserId int, postId int, userId int
All related fields have FK constraints between tables.
I've built this query in SQL but couldn't find a way to work in Entity Framework:
SELECT u.email
FROM Users u
INNER JOIN Posts p ON p.userId != u.userId
LEFT JOIN PostAlertUsers pu ON u.userId = pu.userId AND p.postId = pu.postId
WHERE pu.postAlertUserId IS NULL
I've wrote the following EF query, but didn't got the same results:
from u in context.Users
join pu in context.PostAlertUsers on u.userId equals pu.userId into postAlerts
from pa in postAlerts.DefaultIfEmpty()
join p in context.Posts on pa.postId equals p.postId
where pa.userId != u.userId
select u.email;
How can I get the same results using linq to entities. Using the dot syntax (I don't know the correct term for DbSet.Where(x => ...) syntax) would be even better.
Edit:
I want to get all users that didn't have a record on PostAlertUsers for each Post in Posts that isn't from the same user.
Edit 2:
Trying to clarify a bit more:
I want to warn users about new posts from other users only one time for each post and my routine will run every hour to check if there are anyone to send a message.
I want to get all users that aren't already warned about a post so it will not have a record on PostAlertUsers for this user and post combination but will have a record on Posts from a user other that itself.
Example data:
Users
------------------------
userid | email
------------------------
1 | email1#test.com
2 | email2#test.com
3 | email3#test.com
------------------------
Posts (posts are created by users)
------------------------
postId | userId
------------------------
1 | 1
2 | 3
3 | 1
------------------------
PostAlertUsers (every time a user is notified about a new post, one record is added here)
------------------------
postId | userId
------------------------
1 | 2
1 | 3
2 | 1
------------------------
The resulting query would output this data:
Result (using postId and userId to identify what user have to be notified for what post)
---------------------------------
postId | userId | email
---------------------------------
2 | 2 | email2#test.com
3 | 2 | email2#test.com
3 | 3 | email3#test.com
---------------------------------
Edit:
Thanks to AD.Net I've came up with the following:
from u in context.Users
let posts = contexto.Posts.Where(p => p.userId != u.userId)
from p in posts
join pau in context.PostAlertUsers on u.userId equals pau.userId
into alerts
from a in alerts.DefaultIfEmpty()
where a == null || a.postId != p.postId
orderby p.idPost
select new {
p.postId,
u.userId,
u.email
}
edited:
Another attempt from different angle, not sure about performance, might be just as bad as cross-join
from p in context.Posts
let otherUsers = context.Users.Where(u => u.UserId != p.User.UserId)
from u in otherUsers
join pau in alerts on u.UserId equals pau.User.UserId into alert
from a in alert.DefaultIfEmpty()
where a == null || a.Post.PostId != p.PostId
select new {p.PostId, u.Email};
Here's a LinqPad attempt:
void Main()
{
var users = new List<User>{new User{UserId = 1}, new User{UserId = 2}};
var posts = new List<Post>
{
new Post{PostId = 1, User = new User{UserId = 2}},
new Post{PostId = 2, User = new User{UserId = 1}},
new Post{PostId = 3, User = new User{UserId = 2}},
};
var alerts = new List<PostUserAlert>
{
new PostUserAlert{Post = new Post{PostId = 1},
User = new User{UserId = 1}}
};
var result = (from p in posts
let otherUsers = users.Where(u => u.UserId != p.User.UserId)
from u in otherUsers
join pau in alerts on u.UserId equals pau.User.UserId into alert
from a in alert.DefaultIfEmpty()
where a == null || a.Post.PostId != p.PostId
select new {p.PostId, u.UserId}).ToList();
result.Dump();
}
class User
{
public int UserId { get; set; }
public string Email { get; set; }
}
class Post
{
public int PostId { get; set; }
public User User { get; set; }
public List<PostUserAlert> PostUserAlerts { get; set; }
}
class PostUserAlert
{
public Post Post { get; set; }
public User User { get; set; }
}
// Define other methods and classes here

asp.Net GridView bind custom object with nested List

I have a List of custom object, which consist of a custom list.
class person{
string name;
int age;
List<friend> allMyFriends;
}
class friend{
string name;
string address;
}
I'trying to bind a list of these objects to a GridView and the Grid should create for each friend a column and write the name in it. If some people have the same frined the grid shouldn't create a seperate column, but use the existing one. You know what I mean.
(The classes are just some sample classes to simplify my case)
Is there a way to dynamically customize the binding?
I can change the class definitions and so on, if they need to inherit from some interfaces or so on.
I googled a lot, but no example really seemed to cover this case.
Could the use of a objectSourceControl solve my problem in some way?
Update:
To give some more information:
In the end I have a list of persons, while each person in the list has a list of friends.
List<person> allPerson = new List<person>();
// fill the list
Grid.DataSource = allPerson;
Grid.DataBind()
The table should have columns for each friend and the rows are the person. Where a person has a friend a cross (or whatever) needs to be placed in the grid.
friend1 friend2
x peter
x x adam
At the moment a intercept the RowDataBound event and since the binding only creates the rows with the names and not the columns, because the only property on my person object is the name. Is there a way to force the binding to look through the List Property in the person objects and create a column for each of them.
I was able to solve this using a DataTable as your datasource for the Grid. I don't like the idea of moving from a nice clean object to a DataTable, but it provides support for the dynamic binding you need. I modified your friend object to have a few constructors. This allowed me to cleanup the static code declaration but might not be necessary in your implmentation.
The basic idea is that you will step through all possible friends, add their name as a DataColumn in a DataTable, then fill in the data for all person objects and their respective friends. This could probably be written to work in a single iteration of the allPerson object but I preferred two iterations to make the code easier to read.
The solution is written for c# 3.5 but could be converted for older versions by changing the static data declaration. I hope this helps.
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// setup your person object with static data for testing
List<person> allPerson = new List<person>()
{
new person()
{
name = "Dan",
age = 21,
allMyFriends = new List<friend>() { new friend("James"), new friend("John"), new friend("Matt") }
},
new person()
{
name = "James",
age = 21,
allMyFriends = new List<friend>() { new friend("Dan"), new friend("Matt"), new friend("Tom") }
},
new person()
{
name = "John",
age = 21,
allMyFriends = new List<friend>() { new friend("Dan") }
},
new person()
{
name = "Matt",
age = 21,
allMyFriends = new List<friend>() { new friend("Dan"), new friend("James") }
},
new person()
{
name = "Tom",
age = 21,
allMyFriends = new List<friend>() { new friend("James") }
}
};
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Age");
foreach (person p in allPerson)
{
// step through each person and look at their friends
foreach (friend f in p.allMyFriends)
{
// look to see if this friend has a column already
if (!dt.Columns.Contains(f.name))
{
dt.Columns.Add(f.name);
}
}
}
foreach (person p in allPerson)
{
// create the datarow that represents the person
System.Data.DataRow dr = dt.NewRow();
dr["Name"] = p.name;
dr["Age"] = p.age;
// find the friends and mark them
foreach (friend f in p.allMyFriends)
{
dr[f.name] = "X";
}
dt.Rows.Add(dr);
}
// fill the list
this.Grid.DataSource = dt;
this.Grid.DataBind();
}
}
public class person
{
public string name;
public int age;
public List<friend> allMyFriends = new List<friend>();
}
public class friend
{
public string name;
public string address;
public friend()
{
}
public friend(string name)
{
this.name = name;
}
public friend(string name, string address)
{
this.name = name;
this.address = address;
}
}
Edit:
I forgot to add how this is rendered.
-------------------------------------------------
| Name | Age | James | John | Matt | Dan | Tom |
-------------------------------------------------
| Dan | 21 | X | X | X | | |
| James | 21 | | | X | X | X |
| John | 21 | | | | X | |
| Matt | 21 | X | | | X | |
| Tom | 21 | X | | | | |
-------------------------------------------------
It sounds like you are trying to display a matrix / crosstab in GridView. You might find it easier to grab your retrieve your data in a format more compatible to this. You could consider writing a crosstab query if you are using SQL server.
If you must work with the objects in their current form, Creating a merged list of friends before starting could also help by providing the column list. You could then bind to each column to a function call which could attempt to find the column person in the rows friend list.
Not beautiful, but could work...
You could also just use the RowDataBound event handler to do complex bindings.
use the following :
DataBinder.Eval(Container.DataItem,"PPP.PPP")

Resources