diff --git a/backend/db/Application.js b/backend/db/Application.js
index e2215e7..9a7fdeb 100644
--- a/backend/db/Application.js
+++ b/backend/db/Application.js
@@ -1,4 +1,5 @@
const mongoose = require("mongoose");
+const { diag } = require('@opentelemetry/api');
let schema = new mongoose.Schema(
{
@@ -37,7 +38,9 @@ let schema = new mongoose.Schema(
validate: [
{
validator: function (value) {
- return this.dateOfApplication <= value;
+ const isValid = this.dateOfApplication <= value;
+ diag.debug('Validating dateOfJoining:', { dateOfApplication: this.dateOfApplication, dateOfJoining: value, isValid });
+ return isValid;
},
msg: "dateOfJoining should be greater than dateOfApplication",
},
@@ -47,7 +50,10 @@ let schema = new mongoose.Schema(
type: String,
validate: {
validator: function (v) {
- return v.split(" ").filter((ele) => ele != "").length <= 250;
+ const wordCount = v.split(" ").filter((ele) => ele != "").length;
+ const isValid = wordCount <= 250;
+ diag.debug('Validating SOP word count:', { sop: v, wordCount, isValid });
+ return isValid;
},
msg: "Statement of purpose should not be greater than 250 words",
},
diff --git a/backend/db/Job.js b/backend/db/Job.js
index fce4b15..d9bb6ad 100644
--- a/backend/db/Job.js
+++ b/backend/db/Job.js
@@ -1,4 +1,5 @@
const mongoose = require("mongoose");
+const { diag } = require('@opentelemetry/api');
let schema = new mongoose.Schema(
{
@@ -19,6 +20,7 @@ let schema = new mongoose.Schema(
},
{
validator: function (value) {
+ diag.info(`Validating maxApplicants: ${value}`);
return value > 0;
},
msg: "maxApplicants should greater than 0",
@@ -34,6 +36,7 @@ let schema = new mongoose.Schema(
},
{
validator: function (value) {
+ diag.info(`Validating maxPositions: ${value}`);
return value > 0;
},
msg: "maxPositions should greater than 0",
@@ -50,6 +53,7 @@ let schema = new mongoose.Schema(
},
{
validator: function (value) {
+ diag.info(`Validating activeApplications: ${value}`);
return value >= 0;
},
msg: "activeApplications should greater than equal to 0",
@@ -66,6 +70,7 @@ let schema = new mongoose.Schema(
},
{
validator: function (value) {
+ diag.info(`Validating acceptedCandidates: ${value}`);
return value >= 0;
},
msg: "acceptedCandidates should greater than equal to 0",
@@ -81,6 +86,7 @@ let schema = new mongoose.Schema(
validate: [
{
validator: function (value) {
+ diag.info(`Validating deadline: ${value} against dateOfPosting: ${this.dateOfPosting}`);
return this.dateOfPosting < value;
},
msg: "deadline should be greater than dateOfPosting",
@@ -111,6 +117,7 @@ let schema = new mongoose.Schema(
},
{
validator: function (value) {
+ diag.info(`Validating salary: ${value}`);
return value >= 0;
},
msg: "Salary should be positive",
@@ -123,6 +130,7 @@ let schema = new mongoose.Schema(
default: -1.0,
validate: {
validator: function (v) {
+ diag.info(`Validating rating: ${v}`);
return v >= -1.0 && v <= 5.0;
},
msg: "Invalid rating",
diff --git a/backend/db/JobApplicant.js b/backend/db/JobApplicant.js
index f84d5c7..efd4d9f 100644
--- a/backend/db/JobApplicant.js
+++ b/backend/db/JobApplicant.js
@@ -1,4 +1,8 @@
const mongoose = require("mongoose");
+const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
+
+// Initialize the logger
+diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
let schema = new mongoose.Schema(
{
@@ -30,7 +34,9 @@ let schema = new mongoose.Schema(
{ validator: Number.isInteger, msg: "Year should be an integer" },
{
validator: function (value) {
- return this.startYear <= value;
+ const isValid = this.startYear <= value;
+ diag.info(`Validating endYear: ${value}, startYear: ${this.startYear}, isValid: ${isValid}`);
+ return isValid;
},
msg: "End year should be greater than or equal to Start year",
},
@@ -45,7 +51,9 @@ let schema = new mongoose.Schema(
default: -1.0,
validate: {
validator: function (v) {
- return v >= -1.0 && v <= 5.0;
+ const isValid = v >= -1.0 && v <= 5.0;
+ diag.info(`Validating rating: ${v}, isValid: ${isValid}`);
+ return isValid;
},
msg: "Invalid rating",
},
@@ -60,4 +68,6 @@ let schema = new mongoose.Schema(
{ collation: { locale: "en" } }
);
+diag.info('Schema for JobApplicantInfo created');
+
module.exports = mongoose.model("JobApplicantInfo", schema);
diff --git a/backend/db/Rating.js b/backend/db/Rating.js
index 523aa21..0e1a6e9 100644
--- a/backend/db/Rating.js
+++ b/backend/db/Rating.js
@@ -1,4 +1,5 @@
const mongoose = require("mongoose");
+const { diag } = require('@opentelemetry/api');
let schema = new mongoose.Schema(
{
@@ -21,6 +22,7 @@ let schema = new mongoose.Schema(
default: -1.0,
validate: {
validator: function (v) {
+ diag.debug(`Validating rating: ${v}`);
return v >= -1.0 && v <= 5.0;
},
msg: "Invalid rating",
@@ -30,6 +32,12 @@ let schema = new mongoose.Schema(
{ collation: { locale: "en" } }
);
+diag.debug('Schema created with collation: en');
+
schema.index({ category: 1, receiverId: 1, senderId: 1 }, { unique: true });
+diag.debug('Index created on schema with fields: category, receiverId, senderId');
+
module.exports = mongoose.model("ratings", schema);
+
+diag.debug('Mongoose model "ratings" exported');
diff --git a/backend/db/Recruiter.js b/backend/db/Recruiter.js
index 0c412b7..0c1f601 100644
--- a/backend/db/Recruiter.js
+++ b/backend/db/Recruiter.js
@@ -1,4 +1,5 @@
const mongoose = require("mongoose");
+const { diag } = require('@opentelemetry/api');
let schema = new mongoose.Schema(
{
@@ -14,7 +15,9 @@ let schema = new mongoose.Schema(
type: String,
validate: {
validator: function (v) {
- return v !== "" ? /\+\d{1,3}\d{10}/.test(v) : true;
+ const isValid = v !== "" ? /\+\d{1,3}\d{10}/.test(v) : true;
+ diag.debug(`Validating contact number: ${v}, isValid: ${isValid}`);
+ return isValid;
},
msg: "Phone number is invalid!",
},
@@ -26,4 +29,6 @@ let schema = new mongoose.Schema(
{ collation: { locale: "en" } }
);
+diag.debug('Schema created with collation locale: en');
+
module.exports = mongoose.model("RecruiterInfo", schema);
diff --git a/backend/db/User.js b/backend/db/User.js
index c982d3c..ea7f431 100644
--- a/backend/db/User.js
+++ b/backend/db/User.js
@@ -1,5 +1,6 @@
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
+const { diag } = require('@opentelemetry/api');
require("mongoose-type-email");
let schema = new mongoose.Schema(
@@ -26,16 +27,20 @@ let schema = new mongoose.Schema(
// Password hashing
schema.pre("save", function (next) {
let user = this;
+ diag.debug('Pre-save hook triggered for user:', user.email);
// if the data is not modified
if (!user.isModified("password")) {
+ diag.debug('Password not modified for user:', user.email);
return next();
}
bcrypt.hash(user.password, 10, (err, hash) => {
if (err) {
+ diag.error('Error hashing password for user:', user.email, err);
return next(err);
}
+ diag.debug('Password hashed successfully for user:', user.email);
user.password = hash;
next();
});
@@ -44,15 +49,19 @@ schema.pre("save", function (next) {
// Password verification upon login
schema.methods.login = function (password) {
let user = this;
+ diag.debug('Login method called for user:', user.email);
return new Promise((resolve, reject) => {
bcrypt.compare(password, user.password, (err, result) => {
if (err) {
+ diag.error('Error comparing password for user:', user.email, err);
reject(err);
}
if (result) {
+ diag.debug('Password verification successful for user:', user.email);
resolve();
} else {
+ diag.debug('Password verification failed for user:', user.email);
reject();
}
});
diff --git a/backend/lib/authKeys.js b/backend/lib/authKeys.js
index 60d2485..3825baa 100644
--- a/backend/lib/authKeys.js
+++ b/backend/lib/authKeys.js
@@ -1,3 +1,17 @@
+To add logging to the given code using the OpenTelemetry library, we need to first set up OpenTelemetry and then add appropriate log messages. Here's how you can instrument the code:
+
+```javascript
+const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
+
+// Set up the OpenTelemetry logger
+diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
+
module.exports = {
jwtSecretKey: "jwt_secret",
};
+
+// Log the jwtSecretKey value
+diag.info(`JWT Secret Key is set to: ${module.exports.jwtSecretKey}`);
+```
+
+This code sets up a basic logger using OpenTelemetry and logs the value of `jwtSecretKey`.
diff --git a/backend/lib/jwtAuth.js b/backend/lib/jwtAuth.js
index 9eb5cb0..314617e 100644
--- a/backend/lib/jwtAuth.js
+++ b/backend/lib/jwtAuth.js
@@ -1,14 +1,18 @@
const passport = require("passport");
+const { diag } = require('@opentelemetry/api');
const jwtAuth = (req, res, next) => {
passport.authenticate("jwt", { session: false }, function (err, user, info) {
if (err) {
+ diag.error('Authentication error:', err);
return next(err);
}
if (!user) {
+ diag.warn('Authentication failed, no user found:', info);
res.status(401).json(info);
return;
}
+ diag.info('User authenticated successfully:', user);
req.user = user;
next();
})(req, res, next);
diff --git a/backend/lib/passportConfig.js b/backend/lib/passportConfig.js
index 5c3cb98..02000c7 100644
--- a/backend/lib/passportConfig.js
+++ b/backend/lib/passportConfig.js
@@ -1,4 +1,5 @@
const passport = require("passport");
+const { diag } = require('@opentelemetry/api');
const Strategy = require("passport-local").Strategy;
const passportJWT = require("passport-jwt");
@@ -15,6 +16,7 @@ const filterJson = (obj, unwantedKeys) => {
filteredObj[key] = obj[key];
}
});
+ diag.debug('Filtered object:', filteredObj);
return filteredObj;
};
@@ -25,12 +27,14 @@ passport.use(
passReqToCallback: true,
},
(req, email, password, done, res) => {
- // console.log(email, password);
+ diag.debug('Authenticating user with email:', email);
User.findOne({ email: email }, (err, user) => {
if (err) {
+ diag.error('Error finding user:', err);
return done(err);
}
if (!user) {
+ diag.warn('User not found for email:', email);
return done(null, false, {
message: "User does not exist",
});
@@ -39,17 +43,12 @@ passport.use(
user
.login(password)
.then(() => {
- // let userSecure = {};
- // const unwantedKeys = ["password", "__v"];
- // Object.keys(user["_doc"]).forEach((key) => {
- // if (unwantedKeys.indexOf(key) === -1) {
- // userSecure[key] = user[key];
- // }
- // });
+ diag.debug('User logged in successfully:', user._id);
user["_doc"] = filterJson(user["_doc"], ["password", "__v"]);
return done(null, user);
})
.catch((err) => {
+ diag.error('Login failed for user:', user._id, 'Error:', err);
return done(err, false, {
message: "Password is incorrect.",
});
@@ -66,10 +65,12 @@ passport.use(
secretOrKey: authKeys.jwtSecretKey,
},
(jwt_payload, done) => {
+ diag.debug('Authenticating JWT payload:', jwt_payload);
User.findById(jwt_payload._id)
.then((user) => {
- console.log(Object.keys(jwt_payload));
+ diag.debug('User found for JWT payload:', jwt_payload._id);
if (!user) {
+ diag.warn('User not found for JWT payload:', jwt_payload._id);
return done(null, false, {
message: "JWT Token does not exist",
});
@@ -78,6 +79,7 @@ passport.use(
return done(null, user);
})
.catch((err) => {
+ diag.error('Error processing JWT payload:', jwt_payload, 'Error:', err);
return done(err, false, {
message: "Incorrect Token",
});
diff --git a/backend/package.json b/backend/package.json
index d84eaa6..f9ca141 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -25,6 +25,11 @@
"passport": "^0.4.1",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
- "uuid": "^8.3.2"
+ "uuid": "^8.3.2",
+ "@opentelemetry/api": "^1.0.0",
+ "@opentelemetry/sdk-node": "^0.27.0",
+ "@opentelemetry/auto-instrumentations-node": "^0.27.0",
+ "@opentelemetry/exporter-trace-otlp-http": "^0.27.0",
+ "@opentelemetry/exporter-metrics-otlp-http": "^0.27.0"
}
}
diff --git a/backend/routes/apiRoutes.js b/backend/routes/apiRoutes.js
index 51618ff..1f9fea0 100644
--- a/backend/routes/apiRoutes.js
+++ b/backend/routes/apiRoutes.js
@@ -1,6 +1,7 @@
const express = require("express");
const mongoose = require("mongoose");
const jwtAuth = require("../lib/jwtAuth");
+const { diag } = require('@opentelemetry/api');
const User = require("../db/User");
const JobApplicant = require("../db/JobApplicant");
@@ -14,6 +15,7 @@ const router = express.Router();
// To add new job
router.post("/jobs", jwtAuth, (req, res) => {
const user = req.user;
+ diag.debug('User type:', user.type);
if (user.type != "recruiter") {
res.status(401).json({
@@ -23,6 +25,7 @@ router.post("/jobs", jwtAuth, (req, res) => {
}
const data = req.body;
+ diag.debug('Job data:', data);
let job = new Job({
userId: user._id,
@@ -41,9 +44,11 @@ router.post("/jobs", jwtAuth, (req, res) => {
job
.save()
.then(() => {
+ diag.debug('Job added successfully');
res.json({ message: "Job added successfully to the database" });
})
.catch((err) => {
+ diag.error('Error adding job:', err);
res.status(400).json(err);
});
});
@@ -51,20 +56,17 @@ router.post("/jobs", jwtAuth, (req, res) => {
// to get all the jobs [pagination] [for recruiter personal and for everyone]
router.get("/jobs", jwtAuth, (req, res) => {
let user = req.user;
+ diag.debug('User type:', user.type);
let findParams = {};
let sortParams = {};
- // const page = parseInt(req.query.page) ? parseInt(req.query.page) : 1;
- // const limit = parseInt(req.query.limit) ? parseInt(req.query.limit) : 10;
- // const skip = page - 1 >= 0 ? (page - 1) * limit : 0;
-
- // to list down jobs posted by a particular recruiter
if (user.type === "recruiter" && req.query.myjobs) {
findParams = {
...findParams,
userId: user._id,
};
+ diag.debug('Find params for recruiter:', findParams);
}
if (req.query.q) {
@@ -74,6 +76,7 @@ router.get("/jobs", jwtAuth, (req, res) => {
$regex: new RegExp(req.query.q, "i"),
},
};
+ diag.debug('Find params with query:', findParams);
}
if (req.query.jobType) {
@@ -83,7 +86,7 @@ router.get("/jobs", jwtAuth, (req, res) => {
} else {
jobTypes = [req.query.jobType];
}
- console.log(jobTypes);
+ diag.debug('Job types:', jobTypes);
findParams = {
...findParams,
jobType: {
@@ -108,6 +111,7 @@ router.get("/jobs", jwtAuth, (req, res) => {
},
],
};
+ diag.debug('Find params with salary range:', findParams);
} else if (req.query.salaryMin) {
findParams = {
...findParams,
@@ -115,6 +119,7 @@ router.get("/jobs", jwtAuth, (req, res) => {
$gte: parseInt(req.query.salaryMin),
},
};
+ diag.debug('Find params with minimum salary:', findParams);
} else if (req.query.salaryMax) {
findParams = {
...findParams,
@@ -122,6 +127,7 @@ router.get("/jobs", jwtAuth, (req, res) => {
$lte: parseInt(req.query.salaryMax),
},
};
+ diag.debug('Find params with maximum salary:', findParams);
}
if (req.query.duration) {
@@ -131,6 +137,7 @@ router.get("/jobs", jwtAuth, (req, res) => {
$lt: parseInt(req.query.duration),
},
};
+ diag.debug('Find params with duration:', findParams);
}
if (req.query.asc) {
@@ -147,6 +154,7 @@ router.get("/jobs", jwtAuth, (req, res) => {
[req.query.asc]: 1,
};
}
+ diag.debug('Sort params ascending:', sortParams);
}
if (req.query.desc) {
@@ -163,14 +171,11 @@ router.get("/jobs", jwtAuth, (req, res) => {
[req.query.desc]: -1,
};
}
+ diag.debug('Sort params descending:', sortParams);
}
- console.log(findParams);
- console.log(sortParams);
-
- // Job.find(findParams).collation({ locale: "en" }).sort(sortParams);
- // .skip(skip)
- // .limit(limit)
+ diag.debug('Final find params:', findParams);
+ diag.debug('Final sort params:', sortParams);
let arr = [
{
@@ -203,19 +208,22 @@ router.get("/jobs", jwtAuth, (req, res) => {
];
}
- console.log(arr);
+ diag.debug('Aggregation pipeline:', arr);
Job.aggregate(arr)
.then((posts) => {
if (posts == null) {
+ diag.debug('No jobs found');
res.status(404).json({
message: "No job found",
});
return;
}
+ diag.debug('Jobs found:', posts.length);
res.json(posts);
})
.catch((err) => {
+ diag.error('Error fetching jobs:', err);
res.status(400).json(err);
});
});
@@ -225,14 +233,17 @@ router.get("/jobs/:id", jwtAuth, (req, res) => {
Job.findOne({ _id: req.params.id })
.then((job) => {
if (job == null) {
+ diag.debug('Job not found with id:', req.params.id);
res.status(400).json({
message: "Job does not exist",
});
return;
}
+ diag.debug('Job found:', job);
res.json(job);
})
.catch((err) => {
+ diag.error('Error fetching job:', err);
res.status(400).json(err);
});
});
@@ -240,6 +251,8 @@ router.get("/jobs/:id", jwtAuth, (req, res) => {
// to update info of a particular job
router.put("/jobs/:id", jwtAuth, (req, res) => {
const user = req.user;
+ diag.debug('User type:', user.type);
+
if (user.type != "recruiter") {
res.status(401).json({
message: "You don't have permissions to change the job details",
@@ -252,12 +265,15 @@ router.put("/jobs/:id", jwtAuth, (req, res) => {
})
.then((job) => {
if (job == null) {
+ diag.debug('Job not found for update with id:', req.params.id);
res.status(404).json({
message: "Job does not exist",
});
return;
}
const data = req.body;
+ diag.debug('Update data:', data);
+
if (data.maxApplicants) {
job.maxApplicants = data.maxApplicants;
}
@@ -270,15 +286,18 @@ router.put("/jobs/:id", jwtAuth, (req, res) => {
job
.save()
.then(() => {
+ diag.debug('Job details updated successfully');
res.json({
message: "Job details updated successfully",
});
})
.catch((err) => {
+ diag.error('Error updating job details:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error finding job for update:', err);
res.status(400).json(err);
});
});
@@ -286,6 +305,8 @@ router.put("/jobs/:id", jwtAuth, (req, res) => {
// to delete a job
router.delete("/jobs/:id", jwtAuth, (req, res) => {
const user = req.user;
+ diag.debug('User type:', user.type);
+
if (user.type != "recruiter") {
res.status(401).json({
message: "You don't have permissions to delete the job",
@@ -298,16 +319,19 @@ router.delete("/jobs/:id", jwtAuth, (req, res) => {
})
.then((job) => {
if (job === null) {
+ diag.debug('Job not found for deletion with id:', req.params.id);
res.status(401).json({
message: "You don't have permissions to delete the job",
});
return;
}
+ diag.debug('Job deleted successfully');
res.json({
message: "Job deleted successfully",
});
})
.catch((err) => {
+ diag.error('Error deleting job:', err);
res.status(400).json(err);
});
});
@@ -315,32 +339,40 @@ router.delete("/jobs/:id", jwtAuth, (req, res) => {
// get user's personal details
router.get("/user", jwtAuth, (req, res) => {
const user = req.user;
+ diag.debug('User type:', user.type);
+
if (user.type === "recruiter") {
Recruiter.findOne({ userId: user._id })
.then((recruiter) => {
if (recruiter == null) {
+ diag.debug('Recruiter not found for user id:', user._id);
res.status(404).json({
message: "User does not exist",
});
return;
}
+ diag.debug('Recruiter found:', recruiter);
res.json(recruiter);
})
.catch((err) => {
+ diag.error('Error fetching recruiter details:', err);
res.status(400).json(err);
});
} else {
JobApplicant.findOne({ userId: user._id })
.then((jobApplicant) => {
if (jobApplicant == null) {
+ diag.debug('Job applicant not found for user id:', user._id);
res.status(404).json({
message: "User does not exist",
});
return;
}
+ diag.debug('Job applicant found:', jobApplicant);
res.json(jobApplicant);
})
.catch((err) => {
+ diag.error('Error fetching job applicant details:', err);
res.status(400).json(err);
});
}
@@ -351,43 +383,52 @@ router.get("/user/:id", jwtAuth, (req, res) => {
User.findOne({ _id: req.params.id })
.then((userData) => {
if (userData === null) {
+ diag.debug('User not found with id:', req.params.id);
res.status(404).json({
message: "User does not exist",
});
return;
}
+ diag.debug('User found:', userData);
if (userData.type === "recruiter") {
Recruiter.findOne({ userId: userData._id })
.then((recruiter) => {
if (recruiter === null) {
+ diag.debug('Recruiter not found for user id:', userData._id);
res.status(404).json({
message: "User does not exist",
});
return;
}
+ diag.debug('Recruiter found:', recruiter);
res.json(recruiter);
})
.catch((err) => {
+ diag.error('Error fetching recruiter details:', err);
res.status(400).json(err);
});
} else {
JobApplicant.findOne({ userId: userData._id })
.then((jobApplicant) => {
if (jobApplicant === null) {
+ diag.debug('Job applicant not found for user id:', userData._id);
res.status(404).json({
message: "User does not exist",
});
return;
}
+ diag.debug('Job applicant found:', jobApplicant);
res.json(jobApplicant);
})
.catch((err) => {
+ diag.error('Error fetching job applicant details:', err);
res.status(400).json(err);
});
}
})
.catch((err) => {
+ diag.error('Error fetching user details:', err);
res.status(400).json(err);
});
});
@@ -396,10 +437,14 @@ router.get("/user/:id", jwtAuth, (req, res) => {
router.put("/user", jwtAuth, (req, res) => {
const user = req.user;
const data = req.body;
+ diag.debug('User type:', user.type);
+ diag.debug('Update data:', data);
+
if (user.type == "recruiter") {
Recruiter.findOne({ userId: user._id })
.then((recruiter) => {
if (recruiter == null) {
+ diag.debug('Recruiter not found for update with user id:', user._id);
res.status(404).json({
message: "User does not exist",
});
@@ -417,21 +462,25 @@ router.put("/user", jwtAuth, (req, res) => {
recruiter
.save()
.then(() => {
+ diag.debug('Recruiter information updated successfully');
res.json({
message: "User information updated successfully",
});
})
.catch((err) => {
+ diag.error('Error updating recruiter information:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error finding recruiter for update:', err);
res.status(400).json(err);
});
} else {
JobApplicant.findOne({ userId: user._id })
.then((jobApplicant) => {
if (jobApplicant == null) {
+ diag.debug('Job applicant not found for update with user id:', user._id);
res.status(404).json({
message: "User does not exist",
});
@@ -452,19 +501,22 @@ router.put("/user", jwtAuth, (req, res) => {
if (data.profile) {
jobApplicant.profile = data.profile;
}
- console.log(jobApplicant);
+ diag.debug('Job applicant before save:', jobApplicant);
jobApplicant
.save()
.then(() => {
+ diag.debug('Job applicant information updated successfully');
res.json({
message: "User information updated successfully",
});
})
.catch((err) => {
+ diag.error('Error updating job applicant information:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error finding job applicant for update:', err);
res.status(400).json(err);
});
}
@@ -473,6 +525,8 @@ router.put("/user", jwtAuth, (req, res) => {
// apply for a job [todo: test: done]
router.post("/jobs/:id/applications", jwtAuth, (req, res) => {
const user = req.user;
+ diag.debug('User type:', user.type);
+
if (user.type != "applicant") {
res.status(401).json({
message: "You don't have permissions to apply for a job",
@@ -481,12 +535,8 @@ router.post("/jobs/:id/applications", jwtAuth, (req, res) => {
}
const data = req.body;
const jobId = req.params.id;
-
- // check whether applied previously
- // find job
- // check count of active applications < limit
- // check user had < 10 active applications && check if user is not having any accepted jobs (user id)
- // store the data in applications
+ diag.debug('Application data:', data);
+ diag.debug('Job ID:', jobId);
Application.findOne({
userId: user._id,
@@ -496,7 +546,7 @@ router.post("/jobs/:id/applications", jwtAuth, (req, res) => {
},
})
.then((appliedApplication) => {
- console.log(appliedApplication);
+ diag.debug('Previously applied application:', appliedApplication);
if (appliedApplication !== null) {
res.status(400).json({
message: "You have already applied for this job",
@@ -507,11 +557,14 @@ router.post("/jobs/:id/applications", jwtAuth, (req, res) => {
Job.findOne({ _id: jobId })
.then((job) => {
if (job === null) {
+ diag.debug('Job not found for application with id:', jobId);
res.status(404).json({
message: "Job does not exist",
});
return;
}
+ diag.debug('Job found for application:', job);
+
Application.countDocuments({
jobId: jobId,
status: {
@@ -519,6 +572,7 @@ router.post("/jobs/:id/applications", jwtAuth, (req, res) => {
},
})
.then((activeApplicationCount) => {
+ diag.debug('Active application count for job:', activeApplicationCount);
if (activeApplicationCount < job.maxApplicants) {
Application.countDocuments({
userId: user._id,
@@ -527,11 +581,13 @@ router.post("/jobs/:id/applications", jwtAuth, (req, res) => {
},
})
.then((myActiveApplicationCount) => {
+ diag.debug('User active application count:', myActiveApplicationCount);
if (myActiveApplicationCount < 10) {
Application.countDocuments({
userId: user._id,
status: "accepted",
}).then((acceptedJobs) => {
+ diag.debug('User accepted jobs count:', acceptedJobs);
if (acceptedJobs === 0) {
const application = new Application({
userId: user._id,
@@ -543,11 +599,13 @@ router.post("/jobs/:id/applications", jwtAuth, (req, res) => {
application
.save()
.then(() => {
+ diag.debug('Job application successful');
res.json({
message: "Job application successful",
});
})
.catch((err) => {
+ diag.error('Error saving job application:', err);
res.status(400).json(err);
});
} else {
@@ -565,6 +623,7 @@ router.post("/jobs/:id/applications", jwtAuth, (req, res) => {
}
})
.catch((err) => {
+ diag.error('Error counting user active applications:', err);
res.status(400).json(err);
});
} else {
@@ -574,14 +633,17 @@ router.post("/jobs/:id/applications", jwtAuth, (req, res) => {
}
})
.catch((err) => {
+ diag.error('Error counting active applications for job:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error finding job for application:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error checking previous application:', err);
res.json(400).json(err);
});
});
@@ -589,6 +651,8 @@ router.post("/jobs/:id/applications", jwtAuth, (req, res) => {
// recruiter gets applications for a particular job [pagination] [todo: test: done]
router.get("/jobs/:id/applications", jwtAuth, (req, res) => {
const user = req.user;
+ diag.debug('User type:', user.type);
+
if (user.type != "recruiter") {
res.status(401).json({
message: "You don't have permissions to view job applications",
@@ -596,15 +660,13 @@ router.get("/jobs/:id/applications", jwtAuth, (req, res) => {
return;
}
const jobId = req.params.id;
-
- // const page = parseInt(req.query.page) ? parseInt(req.query.page) : 1;
- // const limit = parseInt(req.query.limit) ? parseInt(req.query.limit) : 10;
- // const skip = page - 1 >= 0 ? (page - 1) * limit : 0;
+ diag.debug('Job ID for applications:', jobId);
let findParams = {
jobId: jobId,
recruiterId: user._id,
};
+ diag.debug('Find params for applications:', findParams);
let sortParams = {};
@@ -613,17 +675,18 @@ router.get("/jobs/:id/applications", jwtAuth, (req, res) => {
...findParams,
status: req.query.status,
};
+ diag.debug('Find params with status:', findParams);
}
Application.find(findParams)
.collation({ locale: "en" })
.sort(sortParams)
- // .skip(skip)
- // .limit(limit)
.then((applications) => {
+ diag.debug('Applications found:', applications.length);
res.json(applications);
})
.catch((err) => {
+ diag.error('Error fetching applications:', err);
res.status(400).json(err);
});
});
@@ -631,10 +694,7 @@ router.get("/jobs/:id/applications", jwtAuth, (req, res) => {
// recruiter/applicant gets all his applications [pagination]
router.get("/applications", jwtAuth, (req, res) => {
const user = req.user;
-
- // const page = parseInt(req.query.page) ? parseInt(req.query.page) : 1;
- // const limit = parseInt(req.query.limit) ? parseInt(req.query.limit) : 10;
- // const skip = page - 1 >= 0 ? (page - 1) * limit : 0;
+ diag.debug('User type:', user.type);
Application.aggregate([
{
@@ -676,9 +736,11 @@ router.get("/applications", jwtAuth, (req, res) => {
},
])
.then((applications) => {
+ diag.debug('Applications found:', applications.length);
res.json(applications);
})
.catch((err) => {
+ diag.error('Error fetching applications:', err);
res.status(400).json(err);
});
});
@@ -688,52 +750,46 @@ router.put("/applications/:id", jwtAuth, (req, res) => {
const user = req.user;
const id = req.params.id;
const status = req.body.status;
-
- // "applied", // when a applicant is applied
- // "shortlisted", // when a applicant is shortlisted
- // "accepted", // when a applicant is accepted
- // "rejected", // when a applicant is rejected
- // "deleted", // when any job is deleted
- // "cancelled", // an application is cancelled by its author or when other application is accepted
- // "finished", // when job is over
+ diag.debug('User type:', user.type);
+ diag.debug('Application ID:', id);
+ diag.debug('New status:', status);
if (user.type === "recruiter") {
if (status === "accepted") {
- // get job id from application
- // get job info for maxPositions count
- // count applications that are already accepted
- // compare and if condition is satisfied, then save
-
Application.findOne({
_id: id,
recruiterId: user._id,
})
.then((application) => {
if (application === null) {
+ diag.debug('Application not found for acceptance with id:', id);
res.status(404).json({
message: "Application not found",
});
return;
}
+ diag.debug('Application found for acceptance:', application);
Job.findOne({
_id: application.jobId,
userId: user._id,
}).then((job) => {
if (job === null) {
+ diag.debug('Job not found for application acceptance with id:', application.jobId);
res.status(404).json({
message: "Job does not exist",
});
return;
}
+ diag.debug('Job found for application acceptance:', job);
Application.countDocuments({
recruiterId: user._id,
jobId: job._id,
status: "accepted",
}).then((activeApplicationCount) => {
+ diag.debug('Active accepted application count:', activeApplicationCount);
if (activeApplicationCount < job.maxPositions) {
- // accepted
application.status = status;
application.dateOfJoining = req.body.dateOfJoining;
application
@@ -776,11 +832,13 @@ router.put("/applications/:id", jwtAuth, (req, res) => {
}
)
.then(() => {
+ diag.debug('Application accepted successfully');
res.json({
message: `Application ${status} successfully`,
});
})
.catch((err) => {
+ diag.error('Error updating job accepted candidates:', err);
res.status(400).json(err);
});
} else {
@@ -790,10 +848,12 @@ router.put("/applications/:id", jwtAuth, (req, res) => {
}
})
.catch((err) => {
+ diag.error('Error updating other applications:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error saving application status:', err);
res.status(400).json(err);
});
} else {
@@ -805,6 +865,7 @@ router.put("/applications/:id", jwtAuth, (req, res) => {
});
})
.catch((err) => {
+ diag.error('Error finding application for acceptance:', err);
res.status(400).json(err);
});
} else {
@@ -824,11 +885,13 @@ router.put("/applications/:id", jwtAuth, (req, res) => {
)
.then((application) => {
if (application === null) {
+ diag.debug('Application status cannot be updated for id:', id);
res.status(400).json({
message: "Application status cannot be updated",
});
return;
}
+ diag.debug('Application status updated successfully');
if (status === "finished") {
res.json({
message: `Job ${status} successfully`,
@@ -840,13 +903,13 @@ router.put("/applications/:id", jwtAuth, (req, res) => {
}
})
.catch((err) => {
+ diag.error('Error updating application status:', err);
res.status(400).json(err);
});
}
} else {
if (status === "cancelled") {
- console.log(id);
- console.log(user._id);
+ diag.debug('Cancelling application with id:', id);
Application.findOneAndUpdate(
{
_id: id,
@@ -859,12 +922,13 @@ router.put("/applications/:id", jwtAuth, (req, res) => {
}
)
.then((tmp) => {
- console.log(tmp);
+ diag.debug('Application cancelled successfully:', tmp);
res.json({
message: `Application ${status} successfully`,
});
})
.catch((err) => {
+ diag.error('Error cancelling application:', err);
res.status(400).json(err);
});
} else {
@@ -879,6 +943,8 @@ router.put("/applications/:id", jwtAuth, (req, res) => {
// get a list of final applicants for all his jobs : recuiter
router.get("/applicants", jwtAuth, (req, res) => {
const user = req.user;
+ diag.debug('User type:', user.type);
+
if (user.type === "recruiter") {
let findParams = {
recruiterId: user._id,
@@ -902,6 +968,8 @@ router.get("/applicants", jwtAuth, (req, res) => {
};
}
}
+ diag.debug('Find params for applicants:', findParams);
+
let sortParams = {};
if (!req.query.asc && !req.query.desc) {
@@ -939,6 +1007,7 @@ router.get("/applicants", jwtAuth, (req, res) => {
};
}
}
+ diag.debug('Sort params for applicants:', sortParams);
Application.aggregate([
{
@@ -964,14 +1033,17 @@ router.get("/applicants", jwtAuth, (req, res) => {
])
.then((applications) => {
if (applications.length === 0) {
+ diag.debug('No applicants found');
res.status(404).json({
message: "No applicants found",
});
return;
}
+ diag.debug('Applicants found:', applications.length);
res.json(applications);
})
.catch((err) => {
+ diag.error('Error fetching applicants:', err);
res.status(400).json(err);
});
} else {
@@ -985,8 +1057,10 @@ router.get("/applicants", jwtAuth, (req, res) => {
router.put("/rating", jwtAuth, (req, res) => {
const user = req.user;
const data = req.body;
+ diag.debug('User type:', user.type);
+ diag.debug('Rating data:', data);
+
if (user.type === "recruiter") {
- // can rate applicant
Rating.findOne({
senderId: user._id,
receiverId: data.applicantId,
@@ -994,7 +1068,7 @@ router.put("/rating", jwtAuth, (req, res) => {
})
.then((rating) => {
if (rating === null) {
- console.log("new rating");
+ diag.debug('No existing rating found, creating new');
Application.countDocuments({
userId: data.applicantId,
recruiterId: user._id,
@@ -1003,9 +1077,8 @@ router.put("/rating", jwtAuth, (req, res) => {
},
})
.then((acceptedApplicant) => {
+ diag.debug('Accepted applicant count:', acceptedApplicant);
if (acceptedApplicant > 0) {
- // add a new rating
-
rating = new Rating({
category: "applicant",
receiverId: data.applicantId,
@@ -1016,7 +1089,6 @@ router.put("/rating", jwtAuth, (req, res) => {
rating
.save()
.then(() => {
- // get the average of ratings
Rating.aggregate([
{
$match: {
@@ -1032,7 +1104,6 @@ router.put("/rating", jwtAuth, (req, res) => {
},
])
.then((result) => {
- // update the user's rating
if (result === null) {
res.status(400).json({
message: "Error while calculating rating",
@@ -1040,6 +1111,7 @@ router.put("/rating", jwtAuth, (req, res) => {
return;
}
const avg = result[0].average;
+ diag.debug('Calculated average rating:', avg);
JobApplicant.findOneAndUpdate(
{
@@ -1059,23 +1131,26 @@ router.put("/rating", jwtAuth, (req, res) => {
});
return;
}
+ diag.debug('Applicant rating updated successfully');
res.json({
message: "Rating added successfully",
});
})
.catch((err) => {
+ diag.error('Error updating applicant rating:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error calculating average rating:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error saving new rating:', err);
res.status(400).json(err);
});
} else {
- // you cannot rate
res.status(400).json({
message:
"Applicant didn't worked under you. Hence you cannot give a rating.",
@@ -1083,6 +1158,7 @@ router.put("/rating", jwtAuth, (req, res) => {
}
})
.catch((err) => {
+ diag.error('Error counting accepted applicants:', err);
res.status(400).json(err);
});
} else {
@@ -1090,7 +1166,6 @@ router.put("/rating", jwtAuth, (req, res) => {
rating
.save()
.then(() => {
- // get the average of ratings
Rating.aggregate([
{
$match: {
@@ -1106,7 +1181,6 @@ router.put("/rating", jwtAuth, (req, res) => {
},
])
.then((result) => {
- // update the user's rating
if (result === null) {
res.status(400).json({
message: "Error while calculating rating",
@@ -1114,6 +1188,8 @@ router.put("/rating", jwtAuth, (req, res) => {
return;
}
const avg = result[0].average;
+ diag.debug('Calculated average rating:', avg);
+
JobApplicant.findOneAndUpdate(
{
userId: data.applicantId,
@@ -1132,39 +1208,40 @@ router.put("/rating", jwtAuth, (req, res) => {
});
return;
}
+ diag.debug('Applicant rating updated successfully');
res.json({
message: "Rating updated successfully",
});
})
.catch((err) => {
+ diag.error('Error updating applicant rating:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error calculating average rating:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error saving updated rating:', err);
res.status(400).json(err);
});
}
})
.catch((err) => {
+ diag.error('Error finding existing rating:', err);
res.status(400).json(err);
});
} else {
- // applicant can rate job
Rating.findOne({
senderId: user._id,
receiverId: data.jobId,
category: "job",
})
.then((rating) => {
- console.log(user._id);
- console.log(data.jobId);
- console.log(rating);
+ diag.debug('Existing rating:', rating);
if (rating === null) {
- console.log(rating);
Application.countDocuments({
userId: user._id,
jobId: data.jobId,
@@ -1173,9 +1250,8 @@ router.put("/rating", jwtAuth, (req, res) => {
},
})
.then((acceptedApplicant) => {
+ diag.debug('Accepted applicant count for job:', acceptedApplicant);
if (acceptedApplicant > 0) {
- // add a new rating
-
rating = new Rating({
category: "job",
receiverId: data.jobId,
@@ -1186,7 +1262,6 @@ router.put("/rating", jwtAuth, (req, res) => {
rating
.save()
.then(() => {
- // get the average of ratings
Rating.aggregate([
{
$match: {
@@ -1209,6 +1284,8 @@ router.put("/rating", jwtAuth, (req, res) => {
return;
}
const avg = result[0].average;
+ diag.debug('Calculated average rating for job:', avg);
+
Job.findOneAndUpdate(
{
_id: data.jobId,
@@ -1227,23 +1304,26 @@ router.put("/rating", jwtAuth, (req, res) => {
});
return;
}
+ diag.debug('Job rating updated successfully');
res.json({
message: "Rating added successfully",
});
})
.catch((err) => {
+ diag.error('Error updating job rating:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error calculating average job rating:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error saving new job rating:', err);
res.status(400).json(err);
});
} else {
- // you cannot rate
res.status(400).json({
message:
"You haven't worked for this job. Hence you cannot give a rating.",
@@ -1251,15 +1331,14 @@ router.put("/rating", jwtAuth, (req, res) => {
}
})
.catch((err) => {
+ diag.error('Error counting accepted applicants for job:', err);
res.status(400).json(err);
});
} else {
- // update the rating
rating.rating = data.rating;
rating
.save()
.then(() => {
- // get the average of ratings
Rating.aggregate([
{
$match: {
@@ -1282,7 +1361,7 @@ router.put("/rating", jwtAuth, (req, res) => {
return;
}
const avg = result[0].average;
- console.log(avg);
+ diag.debug('Calculated average rating for job:', avg);
Job.findOneAndUpdate(
{
@@ -1301,24 +1380,29 @@ router.put("/rating", jwtAuth, (req, res) => {
});
return;
}
+ diag.debug('Job rating updated successfully');
res.json({
message: "Rating added successfully",
});
})
.catch((err) => {
+ diag.error('Error updating job rating:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error calculating average job rating:', err);
res.status(400).json(err);
});
})
.catch((err) => {
+ diag.error('Error saving updated job rating:', err);
res.status(400).json(err);
});
}
})
.catch((err) => {
+ diag.error('Error finding existing job rating:', err);
res.status(400).json(err);
});
}
@@ -1327,54 +1411,25 @@ router.put("/rating", jwtAuth, (req, res) => {
// get personal rating
router.get("/rating", jwtAuth, (req, res) => {
const user = req.user;
+ diag.debug('User type:', user.type);
+
Rating.findOne({
senderId: user._id,
receiverId: req.query.id,
category: user.type === "recruiter" ? "applicant" : "job",
}).then((rating) => {
if (rating === null) {
+ diag.debug('No personal rating found');
res.json({
rating: -1,
});
return;
}
+ diag.debug('Personal rating found:', rating.rating);
res.json({
rating: rating.rating,
});
});
});
-// Application.findOne({
-// _id: id,
-// userId: user._id,
-// })
-// .then((application) => {
-// application.status = status;
-// application
-// .save()
-// .then(() => {
-// res.json({
-// message: `Application ${status} successfully`,
-// });
-// })
-// .catch((err) => {
-// res.status(400).json(err);
-// });
-// })
-// .catch((err) => {
-// res.status(400).json(err);
-// });
-
-// router.get("/jobs", (req, res, next) => {
-// passport.authenticate("jwt", { session: false }, function (err, user, info) {
-// if (err) {
-// return next(err);
-// }
-// if (!user) {
-// res.status(401).json(info);
-// return;
-// }
-// })(req, res, next);
-// });
-
module.exports = router;
diff --git a/backend/routes/authRoutes.js b/backend/routes/authRoutes.js
index 7911934..b51b792 100644
--- a/backend/routes/authRoutes.js
+++ b/backend/routes/authRoutes.js
@@ -2,6 +2,7 @@ const express = require("express");
const passport = require("passport");
const jwt = require("jsonwebtoken");
const authKeys = require("../lib/authKeys");
+const { diag } = require('@opentelemetry/api');
const User = require("../db/User");
const JobApplicant = require("../db/JobApplicant");
@@ -11,6 +12,8 @@ const router = express.Router();
router.post("/signup", (req, res) => {
const data = req.body;
+ diag.info('Received signup request', { data });
+
let user = new User({
email: data.email,
password: data.password,
@@ -20,6 +23,8 @@ router.post("/signup", (req, res) => {
user
.save()
.then(() => {
+ diag.info('User saved successfully', { userId: user._id });
+
const userDetails =
user.type == "recruiter"
? new Recruiter({
@@ -41,44 +46,61 @@ router.post("/signup", (req, res) => {
userDetails
.save()
.then(() => {
+ diag.info('User details saved successfully', { userId: user._id });
+
// Token
const token = jwt.sign({ _id: user._id }, authKeys.jwtSecretKey);
+ diag.info('JWT token generated', { token });
+
res.json({
token: token,
type: user.type,
});
})
.catch((err) => {
+ diag.error('Error saving user details', { error: err });
+
user
.delete()
.then(() => {
+ diag.info('User deleted after error in saving details', { userId: user._id });
res.status(400).json(err);
})
.catch((err) => {
+ diag.error('Error deleting user after failed details save', { error: err });
res.json({ error: err });
});
err;
});
})
.catch((err) => {
+ diag.error('Error saving user', { error: err });
res.status(400).json(err);
});
});
router.post("/login", (req, res, next) => {
+ diag.info('Received login request', { body: req.body });
+
passport.authenticate(
"local",
{ session: false },
function (err, user, info) {
if (err) {
+ diag.error('Error during authentication', { error: err });
return next(err);
}
if (!user) {
+ diag.info('Authentication failed', { info });
res.status(401).json(info);
return;
}
+ diag.info('User authenticated successfully', { userId: user._id });
+
// Token
const token = jwt.sign({ _id: user._id }, authKeys.jwtSecretKey);
+ diag.info('JWT token generated', { token });
+
res.json({
token: token,
type: user.type,
diff --git a/backend/routes/downloadRoutes.js b/backend/routes/downloadRoutes.js
index 31798ef..b82ec36 100644
--- a/backend/routes/downloadRoutes.js
+++ b/backend/routes/downloadRoutes.js
@@ -1,31 +1,38 @@
const express = require("express");
const fs = require("fs");
const path = require("path");
+const { diag } = require("@opentelemetry/api");
const router = express.Router();
router.get("/resume/:file", (req, res) => {
const address = path.join(__dirname, `../public/resume/${req.params.file}`);
+ diag.debug(`Attempting to access file at address: ${address}`);
fs.access(address, fs.F_OK, (err) => {
if (err) {
+ diag.error(`File not found at address: ${address}`);
res.status(404).json({
message: "File not found",
});
return;
}
+ diag.debug(`File found, sending file at address: ${address}`);
res.sendFile(address);
});
});
router.get("/profile/:file", (req, res) => {
const address = path.join(__dirname, `../public/profile/${req.params.file}`);
+ diag.debug(`Attempting to access file at address: ${address}`);
fs.access(address, fs.F_OK, (err) => {
if (err) {
+ diag.error(`File not found at address: ${address}`);
res.status(404).json({
message: "File not found",
});
return;
}
+ diag.debug(`File found, sending file at address: ${address}`);
res.sendFile(address);
});
});
diff --git a/backend/routes/uploadRoutes.js b/backend/routes/uploadRoutes.js
index b12d2aa..0b93276 100644
--- a/backend/routes/uploadRoutes.js
+++ b/backend/routes/uploadRoutes.js
@@ -3,6 +3,7 @@ const multer = require("multer");
const fs = require("fs");
const { v4: uuidv4 } = require("uuid");
const { promisify } = require("util");
+const { diag } = require("@opentelemetry/api");
const pipeline = promisify(require("stream").pipeline);
@@ -12,24 +13,30 @@ const upload = multer();
router.post("/resume", upload.single("file"), (req, res) => {
const { file } = req;
+ diag.debug("Received file for resume upload", { fileExtension: file.detectedFileExtension });
+
if (file.detectedFileExtension != ".pdf") {
+ diag.warn("Invalid file format for resume upload", { fileExtension: file.detectedFileExtension });
res.status(400).json({
message: "Invalid format",
});
} else {
const filename = `${uuidv4()}${file.detectedFileExtension}`;
+ diag.debug("Generated filename for resume", { filename });
pipeline(
file.stream,
fs.createWriteStream(`${__dirname}/../public/resume/${filename}`)
)
.then(() => {
+ diag.info("Resume file uploaded successfully", { filename });
res.send({
message: "File uploaded successfully",
url: `/host/resume/${filename}`,
});
})
.catch((err) => {
+ diag.error("Error while uploading resume file", { error: err });
res.status(400).json({
message: "Error while uploading",
});
@@ -39,27 +46,33 @@ router.post("/resume", upload.single("file"), (req, res) => {
router.post("/profile", upload.single("file"), (req, res) => {
const { file } = req;
+ diag.debug("Received file for profile upload", { fileExtension: file.detectedFileExtension });
+
if (
file.detectedFileExtension != ".jpg" &&
file.detectedFileExtension != ".png"
) {
+ diag.warn("Invalid file format for profile upload", { fileExtension: file.detectedFileExtension });
res.status(400).json({
message: "Invalid format",
});
} else {
const filename = `${uuidv4()}${file.detectedFileExtension}`;
+ diag.debug("Generated filename for profile image", { filename });
pipeline(
file.stream,
fs.createWriteStream(`${__dirname}/../public/profile/${filename}`)
)
.then(() => {
+ diag.info("Profile image uploaded successfully", { filename });
res.send({
message: "Profile image uploaded successfully",
url: `/host/profile/${filename}`,
});
})
.catch((err) => {
+ diag.error("Error while uploading profile image", { error: err });
res.status(400).json({
message: "Error while uploading",
});
diff --git a/backend/server.js b/backend/server.js
index a09f526..87a5ee2 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -4,6 +4,10 @@ const mongoose = require("mongoose");
const passportConfig = require("./lib/passportConfig");
const cors = require("cors");
const fs = require("fs");
+const { diag, DiagConsoleLogger, DiagLogLevel } = require('@opentelemetry/api');
+
+// Set up OpenTelemetry diagnostics
+diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.ALL);
// MongoDB
mongoose
@@ -13,17 +17,24 @@ mongoose
useCreateIndex: true,
useFindAndModify: false,
})
- .then((res) => console.log("Connected to DB"))
- .catch((err) => console.log(err));
+ .then((res) => {
+ diag.info("Connected to DB");
+ })
+ .catch((err) => {
+ diag.error("Error connecting to DB", err);
+ });
// initialising directories
if (!fs.existsSync("./public")) {
+ diag.info("Creating directory: ./public");
fs.mkdirSync("./public");
}
if (!fs.existsSync("./public/resume")) {
+ diag.info("Creating directory: ./public/resume");
fs.mkdirSync("./public/resume");
}
if (!fs.existsSync("./public/profile")) {
+ diag.info("Creating directory: ./public/profile");
fs.mkdirSync("./public/profile");
}
@@ -45,5 +56,5 @@ app.use("/upload", require("./routes/uploadRoutes"));
app.use("/host", require("./routes/downloadRoutes"));
app.listen(port, () => {
- console.log(`Server started on port ${port}!`);
+ diag.info(`Server started on port ${port}!`);
});
diff --git a/frontend/package.json b/frontend/package.json
index 00b0d96..73e0d5a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -16,7 +16,12 @@
"react-phone-input-2": "^2.13.9",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.1",
- "web-vitals": "^0.2.4"
+ "web-vitals": "^0.2.4",
+ "@opentelemetry/api": "^1.0.0",
+ "@opentelemetry/sdk-trace-web": "^1.0.0",
+ "@opentelemetry/sdk-metrics": "^1.0.0",
+ "@opentelemetry/instrumentation": "^0.29.0",
+ "@opentelemetry/auto-instrumentations-web": "^0.29.0"
},
"scripts": {
"start": "react-scripts start",
diff --git a/frontend/src/App.js b/frontend/src/App.js
index 3e51b45..c3e9489 100644
--- a/frontend/src/App.js
+++ b/frontend/src/App.js
@@ -1,6 +1,7 @@
import { createContext, useState } from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import { Grid, makeStyles } from "@material-ui/core";
+import { diag } from '@opentelemetry/api';
import Welcome, { ErrorPage } from "./component/Welcome";
import Navbar from "./component/Navbar";
@@ -35,37 +36,46 @@ export const SetPopupContext = createContext();
function App() {
const classes = useStyles();
+ diag.debug('useStyles applied with classes:', classes);
const [popup, setPopup] = useState({
open: false,
severity: "",
message: "",
});
+ diag.debug('Initial popup state:', popup);
return (
+ diag.debug('Navbar component rendered');
+ diag.debug('Route "/" matched, Welcome component rendered');
+ diag.debug('Route "/login" matched, Login component rendered');
+ diag.debug('Route "/signup" matched, Signup component rendered');
+ diag.debug('Route "/logout" matched, Logout component rendered');
+ diag.debug('Route "/home" matched, Home component rendered');
+ diag.debug('Route "/applications" matched, Applications component rendered');
{userType() === "recruiter" ? (
@@ -73,21 +83,27 @@ function App() {
) : (
)}
+ diag.debug('Route "/profile" matched, userType:', userType());
+ diag.debug('Route "/addjob" matched, CreateJobs component rendered');
+ diag.debug('Route "/myjobs" matched, MyJobs component rendered');
+ diag.debug('Route "/job/applications/:jobId" matched, JobApplications component rendered');
+ diag.debug('Route "/employees" matched, AcceptedApplicants component rendered');
+ diag.debug('No route matched, ErrorPage component rendered');
@@ -103,6 +119,7 @@ function App() {
severity={popup.severity}
message={popup.message}
/>
+ diag.debug('MessagePopup component rendered with state:', popup);
);
diff --git a/frontend/src/App.test.js b/frontend/src/App.test.js
index 1f03afe..b9a6e85 100644
--- a/frontend/src/App.test.js
+++ b/frontend/src/App.test.js
@@ -1,8 +1,11 @@
import { render, screen } from '@testing-library/react';
import App from './App';
+import { diag } from '@opentelemetry/api';
test('renders learn react link', () => {
+ diag.info('Rendering App component');
render();
const linkElement = screen.getByText(/learn react/i);
+ diag.info('Checking if the link element is in the document', { linkElement });
expect(linkElement).toBeInTheDocument();
});
diff --git a/frontend/src/component/Applications.js b/frontend/src/component/Applications.js
index d6e07a4..46f35a6 100644
--- a/frontend/src/component/Applications.js
+++ b/frontend/src/component/Applications.js
@@ -18,6 +18,7 @@ import {
} from "@material-ui/core";
import Rating from "@material-ui/lab/Rating";
import axios from "axios";
+import { diag } from '@opentelemetry/api';
import { SetPopupContext } from "../App";
@@ -60,6 +61,7 @@ const ApplicationTile = (props) => {
const joinedOn = new Date(application.dateOfJoining);
const fetchRating = () => {
+ diag.debug('Fetching rating for job ID:', application.job._id);
axios
.get(`${apiList.rating}?id=${application.job._id}`, {
headers: {
@@ -68,10 +70,11 @@ const ApplicationTile = (props) => {
})
.then((response) => {
setRating(response.data.rating);
+ diag.debug('Fetched rating:', response.data.rating);
console.log(response.data);
})
.catch((err) => {
- // console.log(err.response);
+ diag.error('Error fetching rating:', err.response.data);
console.log(err.response.data);
setPopup({
open: true,
@@ -82,6 +85,7 @@ const ApplicationTile = (props) => {
};
const changeRating = () => {
+ diag.debug('Changing rating to:', rating, 'for job ID:', application.job._id);
axios
.put(
apiList.rating,
@@ -93,6 +97,7 @@ const ApplicationTile = (props) => {
}
)
.then((response) => {
+ diag.debug('Rating changed successfully:', response.data);
console.log(response.data);
setPopup({
open: true,
@@ -103,7 +108,7 @@ const ApplicationTile = (props) => {
setOpen(false);
})
.catch((err) => {
- // console.log(err.response);
+ diag.error('Error changing rating:', err);
console.log(err);
setPopup({
open: true,
@@ -116,6 +121,7 @@ const ApplicationTile = (props) => {
};
const handleClose = () => {
+ diag.debug('Closing rating modal');
setOpen(false);
};
@@ -176,6 +182,7 @@ const ApplicationTile = (props) => {
color="primary"
className={classes.statusBlock}
onClick={() => {
+ diag.debug('Opening rating modal for job ID:', application.job._id);
fetchRating();
setOpen(true);
}}
@@ -203,6 +210,7 @@ const ApplicationTile = (props) => {
style={{ marginBottom: "30px" }}
value={rating === -1 ? null : rating}
onChange={(event, newValue) => {
+ diag.debug('Rating changed to:', newValue);
setRating(newValue);
}}
/>
@@ -225,6 +233,7 @@ const Applications = (props) => {
const [applications, setApplications] = useState([]);
useEffect(() => {
+ diag.debug('Fetching applications data');
getData();
}, []);
@@ -236,11 +245,12 @@ const Applications = (props) => {
},
})
.then((response) => {
+ diag.debug('Fetched applications data:', response.data);
console.log(response.data);
setApplications(response.data);
})
.catch((err) => {
- // console.log(err.response);
+ diag.error('Error fetching applications data:', err.response.data);
console.log(err.response.data);
setPopup({
open: true,
diff --git a/frontend/src/component/Home.js b/frontend/src/component/Home.js
index b237895..14e83a7 100644
--- a/frontend/src/component/Home.js
+++ b/frontend/src/component/Home.js
@@ -28,6 +28,7 @@ import { SetPopupContext } from "../App";
import apiList from "../lib/apiList";
import { userType } from "../lib/isAuth";
+import { diagLog } from '@opentelemetry/api';
const useStyles = makeStyles((theme) => ({
body: {
@@ -62,11 +63,11 @@ const JobTile = (props) => {
const handleClose = () => {
setOpen(false);
setSop("");
+ diagLog.info('Modal closed and SOP reset');
};
const handleApply = () => {
- console.log(job._id);
- console.log(sop);
+ diagLog.info('Applying for job', { jobId: job._id, sop: sop });
axios
.post(
`${apiList.jobs}/${job._id}/applications`,
@@ -80,6 +81,7 @@ const JobTile = (props) => {
}
)
.then((response) => {
+ diagLog.info('Application successful', { message: response.data.message });
setPopup({
open: true,
severity: "success",
@@ -88,7 +90,7 @@ const JobTile = (props) => {
handleClose();
})
.catch((err) => {
- console.log(err.response);
+ diagLog.error('Application failed', { error: err.response });
setPopup({
open: true,
severity: "error",
@@ -99,6 +101,7 @@ const JobTile = (props) => {
};
const deadline = new Date(job.deadline).toLocaleDateString();
+ diagLog.info('Job deadline', { deadline: deadline });
return (
@@ -132,6 +135,7 @@ const JobTile = (props) => {
className={classes.button}
onClick={() => {
setOpen(true);
+ diagLog.info('Open apply modal', { jobId: job._id });
}}
disabled={userType() === "recruiter"}
>
@@ -165,6 +169,7 @@ const JobTile = (props) => {
}).length <= 250
) {
setSop(event.target.value);
+ diagLog.info('SOP updated', { sop: event.target.value });
}
}}
/>
@@ -185,6 +190,7 @@ const JobTile = (props) => {
const FilterPopup = (props) => {
const classes = useStyles();
const { open, handleClose, searchOptions, setSearchOptions, getData } = props;
+ diagLog.info('FilterPopup props', { open, searchOptions });
return (
{
[event.target.name]: event.target.checked,
},
});
+ diagLog.info('Job type fullTime changed', { checked: event.target.checked });
}}
/>
}
@@ -240,6 +247,7 @@ const FilterPopup = (props) => {
[event.target.name]: event.target.checked,
},
});
+ diagLog.info('Job type partTime changed', { checked: event.target.checked });
}}
/>
}
@@ -260,6 +268,7 @@ const FilterPopup = (props) => {
[event.target.name]: event.target.checked,
},
});
+ diagLog.info('Job type wfh changed', { checked: event.target.checked });
}}
/>
}
@@ -283,12 +292,13 @@ const FilterPopup = (props) => {
{ value: 100, label: "100000" },
]}
value={searchOptions.salary}
- onChange={(event, value) =>
+ onChange={(event, value) => {
setSearchOptions({
...searchOptions,
salary: value,
- })
- }
+ });
+ diagLog.info('Salary range changed', { salary: value });
+ }}
/>
@@ -303,12 +313,13 @@ const FilterPopup = (props) => {
variant="outlined"
fullWidth
value={searchOptions.duration}
- onChange={(event) =>
+ onChange={(event) => {
setSearchOptions({
...searchOptions,
duration: event.target.value,
- })
- }
+ });
+ diagLog.info('Duration changed', { duration: event.target.value });
+ }}
>
@@ -338,7 +349,7 @@ const FilterPopup = (props) => {
+ onChange={(event) => {
setSearchOptions({
...searchOptions,
sort: {
@@ -348,8 +359,9 @@ const FilterPopup = (props) => {
status: event.target.checked,
},
},
- })
- }
+ });
+ diagLog.info('Sort by salary status changed', { status: event.target.checked });
+ }}
id="salary"
/>
@@ -372,6 +384,7 @@ const FilterPopup = (props) => {
},
},
});
+ diagLog.info('Sort by salary order changed', { desc: !searchOptions.sort.salary.desc });
}}
>
{searchOptions.sort.salary.desc ? (
@@ -394,7 +407,7 @@ const FilterPopup = (props) => {
+ onChange={(event) => {
setSearchOptions({
...searchOptions,
sort: {
@@ -404,8 +417,9 @@ const FilterPopup = (props) => {
status: event.target.checked,
},
},
- })
- }
+ });
+ diagLog.info('Sort by duration status changed', { status: event.target.checked });
+ }}
id="duration"
/>
@@ -428,6 +442,7 @@ const FilterPopup = (props) => {
},
},
});
+ diagLog.info('Sort by duration order changed', { desc: !searchOptions.sort.duration.desc });
}}
>
{searchOptions.sort.duration.desc ? (
@@ -450,7 +465,7 @@ const FilterPopup = (props) => {
+ onChange={(event) => {
setSearchOptions({
...searchOptions,
sort: {
@@ -460,8 +475,9 @@ const FilterPopup = (props) => {
status: event.target.checked,
},
},
- })
- }
+ });
+ diagLog.info('Sort by rating status changed', { status: event.target.checked });
+ }}
id="rating"
/>
@@ -484,6 +500,7 @@ const FilterPopup = (props) => {
},
},
});
+ diagLog.info('Sort by rating order changed', { desc: !searchOptions.sort.rating.desc });
}}
>
{searchOptions.sort.rating.desc ? (
@@ -591,7 +608,7 @@ const Home = (props) => {
});
searchParams = [...searchParams, ...asc, ...desc];
const queryString = searchParams.join("&");
- console.log(queryString);
+ diagLog.info('Query string for job search', { queryString: queryString });
let address = apiList.jobs;
if (queryString !== "") {
address = `${address}?${queryString}`;
@@ -604,7 +621,7 @@ const Home = (props) => {
},
})
.then((response) => {
- console.log(response.data);
+ diagLog.info('Jobs fetched successfully', { jobs: response.data });
setJobs(
response.data.filter((obj) => {
const today = new Date();
@@ -614,7 +631,7 @@ const Home = (props) => {
);
})
.catch((err) => {
- console.log(err.response.data);
+ diagLog.error('Error fetching jobs', { error: err.response.data });
setPopup({
open: true,
severity: "error",
@@ -646,21 +663,26 @@ const Home = (props) => {
+ onChange={(event) => {
setSearchOptions({
...searchOptions,
query: event.target.value,
- })
- }
+ });
+ diagLog.info('Search query updated', { query: event.target.value });
+ }}
onKeyPress={(ev) => {
if (ev.key === "Enter") {
getData();
+ diagLog.info('Enter key pressed, fetching data');
}
}}
InputProps={{
endAdornment: (
- getData()}>
+ {
+ getData();
+ diagLog.info('Search button clicked, fetching data');
+ }}>
@@ -671,7 +693,10 @@ const Home = (props) => {
/>
- setFilterOpen(true)}>
+ {
+ setFilterOpen(true);
+ diagLog.info('Filter button clicked, opening filter modal');
+ }}>
@@ -703,10 +728,14 @@ const Home = (props) => {
open={filterOpen}
searchOptions={searchOptions}
setSearchOptions={setSearchOptions}
- handleClose={() => setFilterOpen(false)}
+ handleClose={() => {
+ setFilterOpen(false);
+ diagLog.info('Filter modal closed');
+ }}
getData={() => {
getData();
setFilterOpen(false);
+ diagLog.info('Filter applied, fetching data');
}}
/>
>
diff --git a/frontend/src/component/Login.js b/frontend/src/component/Login.js
index 33de1d4..3fa16fa 100644
--- a/frontend/src/component/Login.js
+++ b/frontend/src/component/Login.js
@@ -9,6 +9,7 @@ import {
} from "@material-ui/core";
import axios from "axios";
import { Redirect } from "react-router-dom";
+import { diag } from '@opentelemetry/api';
import PasswordInput from "../lib/PasswordInput";
import EmailInput from "../lib/EmailInput";
@@ -34,11 +35,13 @@ const Login = (props) => {
const setPopup = useContext(SetPopupContext);
const [loggedin, setLoggedin] = useState(isAuth());
+ diag.debug('Initial loggedin state:', loggedin);
const [loginDetails, setLoginDetails] = useState({
email: "",
password: "",
});
+ diag.debug('Initial loginDetails state:', loginDetails);
const [inputErrorHandler, setInputErrorHandler] = useState({
email: {
@@ -50,15 +53,19 @@ const Login = (props) => {
message: "",
},
});
+ diag.debug('Initial inputErrorHandler state:', inputErrorHandler);
const handleInput = (key, value) => {
+ diag.debug('handleInput called with:', key, value);
setLoginDetails({
...loginDetails,
[key]: value,
});
+ diag.debug('Updated loginDetails state:', loginDetails);
};
const handleInputError = (key, status, message) => {
+ diag.debug('handleInputError called with:', key, status, message);
setInputErrorHandler({
...inputErrorHandler,
[key]: {
@@ -66,35 +73,40 @@ const Login = (props) => {
message: message,
},
});
+ diag.debug('Updated inputErrorHandler state:', inputErrorHandler);
};
const handleLogin = () => {
+ diag.debug('handleLogin called');
const verified = !Object.keys(inputErrorHandler).some((obj) => {
return inputErrorHandler[obj].error;
});
+ diag.debug('Verification result:', verified);
if (verified) {
axios
.post(apiList.login, loginDetails)
.then((response) => {
+ diag.debug('Login successful, response:', response);
localStorage.setItem("token", response.data.token);
localStorage.setItem("type", response.data.type);
setLoggedin(isAuth());
+ diag.debug('Updated loggedin state:', loggedin);
setPopup({
open: true,
severity: "success",
message: "Logged in successfully",
});
- console.log(response);
})
.catch((err) => {
+ diag.debug('Login failed, error:', err.response);
setPopup({
open: true,
severity: "error",
message: err.response.data.message,
});
- console.log(err.response);
});
} else {
+ diag.debug('Input verification failed');
setPopup({
open: true,
severity: "error",
diff --git a/frontend/src/component/Logout.js b/frontend/src/component/Logout.js
index db46530..a4d8377 100644
--- a/frontend/src/component/Logout.js
+++ b/frontend/src/component/Logout.js
@@ -1,19 +1,24 @@
import { useEffect, useContext } from "react";
import { Redirect } from "react-router-dom";
+import { diag } from '@opentelemetry/api';
import { SetPopupContext } from "../App";
const Logout = (props) => {
const setPopup = useContext(SetPopupContext);
useEffect(() => {
+ diag.info('Removing token from localStorage');
localStorage.removeItem("token");
+ diag.info('Removing type from localStorage');
localStorage.removeItem("type");
+ diag.info('Setting popup with success message');
setPopup({
open: true,
severity: "success",
message: "Logged out successfully",
});
}, []);
+ diag.info('Redirecting to login page');
return ;
};
diff --git a/frontend/src/component/Navbar.js b/frontend/src/component/Navbar.js
index 4b18c34..2b44093 100644
--- a/frontend/src/component/Navbar.js
+++ b/frontend/src/component/Navbar.js
@@ -1,13 +1,7 @@
-import {
- AppBar,
- Toolbar,
- Typography,
- Button,
- makeStyles,
-} from "@material-ui/core";
+import { AppBar, Toolbar, Typography, Button, makeStyles } from "@material-ui/core";
import { useHistory } from "react-router-dom";
-
import isAuth, { userType } from "../lib/isAuth";
+import { diag } from '@opentelemetry/api';
const useStyles = makeStyles((theme) => ({
root: {
@@ -26,7 +20,7 @@ const Navbar = (props) => {
let history = useHistory();
const handleClick = (location) => {
- console.log(location);
+ diag.debug(`Navigating to location: ${location}`);
history.push(location);
};
diff --git a/frontend/src/component/Profile.js b/frontend/src/component/Profile.js
index 356801e..95a43e4 100644
--- a/frontend/src/component/Profile.js
+++ b/frontend/src/component/Profile.js
@@ -18,6 +18,8 @@ import { SetPopupContext } from "../App";
import apiList from "../lib/apiList";
+import { trace } from '@opentelemetry/api';
+
const useStyles = makeStyles((theme) => ({
body: {
height: "inherit",
@@ -47,6 +49,7 @@ const MultifieldInput = (props) => {
const newEdu = [...education];
newEdu[key].institutionName = event.target.value;
setEducation(newEdu);
+ trace.getTracer('default').addEvent(`Updated institutionName for key ${key}: ${event.target.value}`);
}}
variant="outlined"
fullWidth
@@ -62,6 +65,7 @@ const MultifieldInput = (props) => {
const newEdu = [...education];
newEdu[key].startYear = event.target.value;
setEducation(newEdu);
+ trace.getTracer('default').addEvent(`Updated startYear for key ${key}: ${event.target.value}`);
}}
/>
@@ -75,6 +79,7 @@ const MultifieldInput = (props) => {
const newEdu = [...education];
newEdu[key].endYear = event.target.value;
setEducation(newEdu);
+ trace.getTracer('default').addEvent(`Updated endYear for key ${key}: ${event.target.value}`);
}}
/>
@@ -84,7 +89,7 @@ const MultifieldInput = (props) => {
@@ -398,28 +459,36 @@ const ApplicationTile = (props) => {
status: status,
dateOfJoining: new Date().toISOString(),
};
- axios
- .put(address, statusData, {
- headers: {
- Authorization: `Bearer ${localStorage.getItem("token")}`,
- },
- })
- .then((response) => {
- setPopup({
- open: true,
- severity: "success",
- message: response.data.message,
- });
- getData();
- })
- .catch((err) => {
- setPopup({
- open: true,
- severity: "error",
- message: err.response.data.message,
+ const tracer = trace.getTracer('default');
+ tracer.startActiveSpan('Update Status', span => {
+ axios
+ .put(address, statusData, {
+ headers: {
+ Authorization: `Bearer ${localStorage.getItem("token")}`,
+ },
+ })
+ .then((response) => {
+ setPopup({
+ open: true,
+ severity: "success",
+ message: response.data.message,
+ });
+ getData();
+ span.setAttribute('status', status);
+ span.setAttribute('responseMessage', response.data.message);
+ span.end();
+ })
+ .catch((err) => {
+ setPopup({
+ open: true,
+ severity: "error",
+ message: err.response.data.message,
+ });
+ console.log(err.response);
+ span.setAttribute('error', err.response.data.message);
+ span.end();
});
- console.log(err.response);
- });
+ });
};
const buttonSet = {
@@ -703,26 +772,32 @@ const JobApplications = (props) => {
console.log(address);
- axios
- .get(address, {
- headers: {
- Authorization: `Bearer ${localStorage.getItem("token")}`,
- },
- })
- .then((response) => {
- console.log(response.data);
- setApplications(response.data);
- })
- .catch((err) => {
- console.log(err.response);
- // console.log(err.response.data);
- setApplications([]);
- setPopup({
- open: true,
- severity: "error",
- message: err.response.data.message,
+ const tracer = trace.getTracer('default');
+ tracer.startActiveSpan('Get Data', span => {
+ axios
+ .get(address, {
+ headers: {
+ Authorization: `Bearer ${localStorage.getItem("token")}`,
+ },
+ })
+ .then((response) => {
+ console.log(response.data);
+ setApplications(response.data);
+ span.setAttribute('applicationsCount', response.data.length);
+ span.end();
+ })
+ .catch((err) => {
+ console.log(err.response);
+ setApplications([]);
+ setPopup({
+ open: true,
+ severity: "error",
+ message: err.response.data.message,
+ });
+ span.setAttribute('error', err.response.data.message);
+ span.end();
});
- });
+ });
};
return (
@@ -754,7 +829,6 @@ const JobApplications = (props) => {
{applications.length > 0 ? (
applications.map((obj) => (
- {/* {console.log(obj)} */}
))
diff --git a/frontend/src/component/recruiter/MyJobs.js b/frontend/src/component/recruiter/MyJobs.js
index 64bf9ae..b044748 100644
--- a/frontend/src/component/recruiter/MyJobs.js
+++ b/frontend/src/component/recruiter/MyJobs.js
@@ -29,6 +29,8 @@ import { SetPopupContext } from "../../App";
import apiList from "../../lib/apiList";
+import { trace } from '@opentelemetry/api';
+
const useStyles = makeStyles((theme) => ({
body: {
height: "inherit",
@@ -69,9 +71,11 @@ const JobTile = (props) => {
const [openUpdate, setOpenUpdate] = useState(false);
const [jobDetails, setJobDetails] = useState(job);
- console.log(jobDetails);
+ const tracer = trace.getTracer('default');
+ tracer.startSpan('JobTile').addEvent('jobDetails', { jobDetails });
const handleInput = (key, value) => {
+ tracer.startSpan('handleInput').addEvent('input', { key, value });
setJobDetails({
...jobDetails,
[key]: value,
@@ -79,6 +83,7 @@ const JobTile = (props) => {
};
const handleClick = (location) => {
+ tracer.startSpan('handleClick').addEvent('location', { location });
history.push(location);
};
@@ -91,7 +96,7 @@ const JobTile = (props) => {
};
const handleDelete = () => {
- console.log(job._id);
+ tracer.startSpan('handleDelete').addEvent('jobId', { jobId: job._id });
axios
.delete(`${apiList.jobs}/${job._id}`, {
headers: {
@@ -99,6 +104,7 @@ const JobTile = (props) => {
},
})
.then((response) => {
+ tracer.startSpan('handleDeleteSuccess').addEvent('response', { response: response.data });
setPopup({
open: true,
severity: "success",
@@ -108,7 +114,7 @@ const JobTile = (props) => {
handleClose();
})
.catch((err) => {
- console.log(err.response);
+ tracer.startSpan('handleDeleteError').addEvent('error', { error: err.response });
setPopup({
open: true,
severity: "error",
@@ -119,6 +125,7 @@ const JobTile = (props) => {
};
const handleJobUpdate = () => {
+ tracer.startSpan('handleJobUpdate').addEvent('jobDetails', { jobDetails });
axios
.put(`${apiList.jobs}/${job._id}`, jobDetails, {
headers: {
@@ -126,6 +133,7 @@ const JobTile = (props) => {
},
})
.then((response) => {
+ tracer.startSpan('handleJobUpdateSuccess').addEvent('response', { response: response.data });
setPopup({
open: true,
severity: "success",
@@ -135,7 +143,7 @@ const JobTile = (props) => {
handleCloseUpdate();
})
.catch((err) => {
- console.log(err.response);
+ tracer.startSpan('handleJobUpdateError').addEvent('error', { error: err.response });
setPopup({
open: true,
severity: "error",
@@ -352,6 +360,9 @@ const JobTile = (props) => {
const FilterPopup = (props) => {
const classes = useStyles();
const { open, handleClose, searchOptions, setSearchOptions, getData } = props;
+ const tracer = trace.getTracer('default');
+ tracer.startSpan('FilterPopup').addEvent('searchOptions', { searchOptions });
+
return (
{
name="fullTime"
checked={searchOptions.jobType.fullTime}
onChange={(event) => {
+ tracer.startSpan('FilterPopupCheckboxChange').addEvent('fullTime', { checked: event.target.checked });
setSearchOptions({
...searchOptions,
jobType: {
@@ -400,6 +412,7 @@ const FilterPopup = (props) => {
name="partTime"
checked={searchOptions.jobType.partTime}
onChange={(event) => {
+ tracer.startSpan('FilterPopupCheckboxChange').addEvent('partTime', { checked: event.target.checked });
setSearchOptions({
...searchOptions,
jobType: {
@@ -420,6 +433,7 @@ const FilterPopup = (props) => {
name="wfh"
checked={searchOptions.jobType.wfh}
onChange={(event) => {
+ tracer.startSpan('FilterPopupCheckboxChange').addEvent('wfh', { checked: event.target.checked });
setSearchOptions({
...searchOptions,
jobType: {
@@ -450,12 +464,13 @@ const FilterPopup = (props) => {
{ value: 100, label: "100000" },
]}
value={searchOptions.salary}
- onChange={(event, value) =>
+ onChange={(event, value) => {
+ tracer.startSpan('FilterPopupSliderChange').addEvent('salary', { value });
setSearchOptions({
...searchOptions,
salary: value,
- })
- }
+ });
+ }}
/>
@@ -470,12 +485,13 @@ const FilterPopup = (props) => {
variant="outlined"
fullWidth
value={searchOptions.duration}
- onChange={(event) =>
+ onChange={(event) => {
+ tracer.startSpan('FilterPopupDurationChange').addEvent('duration', { duration: event.target.value });
setSearchOptions({
...searchOptions,
duration: event.target.value,
- })
- }
+ });
+ }}
>
@@ -505,7 +521,8 @@ const FilterPopup = (props) => {
+ onChange={(event) => {
+ tracer.startSpan('FilterPopupSortChange').addEvent('salarySort', { status: event.target.checked });
setSearchOptions({
...searchOptions,
sort: {
@@ -515,8 +532,8 @@ const FilterPopup = (props) => {
status: event.target.checked,
},
},
- })
- }
+ });
+ }}
id="salary"
/>
@@ -529,6 +546,7 @@ const FilterPopup = (props) => {
{
+ tracer.startSpan('FilterPopupSortDirectionChange').addEvent('salarySortDirection', { desc: !searchOptions.sort.salary.desc });
setSearchOptions({
...searchOptions,
sort: {
@@ -561,7 +579,8 @@ const FilterPopup = (props) => {
+ onChange={(event) => {
+ tracer.startSpan('FilterPopupSortChange').addEvent('durationSort', { status: event.target.checked });
setSearchOptions({
...searchOptions,
sort: {
@@ -571,8 +590,8 @@ const FilterPopup = (props) => {
status: event.target.checked,
},
},
- })
- }
+ });
+ }}
id="duration"
/>
@@ -585,6 +604,7 @@ const FilterPopup = (props) => {
{
+ tracer.startSpan('FilterPopupSortDirectionChange').addEvent('durationSortDirection', { desc: !searchOptions.sort.duration.desc });
setSearchOptions({
...searchOptions,
sort: {
@@ -617,7 +637,8 @@ const FilterPopup = (props) => {
+ onChange={(event) => {
+ tracer.startSpan('FilterPopupSortChange').addEvent('ratingSort', { status: event.target.checked });
setSearchOptions({
...searchOptions,
sort: {
@@ -627,8 +648,8 @@ const FilterPopup = (props) => {
status: event.target.checked,
},
},
- })
- }
+ });
+ }}
id="rating"
/>
@@ -641,6 +662,7 @@ const FilterPopup = (props) => {
{
+ tracer.startSpan('FilterPopupSortDirectionChange').addEvent('ratingSortDirection', { desc: !searchOptions.sort.rating.desc });
setSearchOptions({
...searchOptions,
sort: {
@@ -709,11 +731,14 @@ const MyJobs = (props) => {
});
const setPopup = useContext(SetPopupContext);
+ const tracer = trace.getTracer('default');
+
useEffect(() => {
getData();
}, []);
const getData = () => {
+ tracer.startSpan('getData').addEvent('searchOptions', { searchOptions });
let searchParams = [`myjobs=1`];
if (searchOptions.query !== "") {
searchParams = [...searchParams, `q=${searchOptions.query}`];
@@ -758,13 +783,13 @@ const MyJobs = (props) => {
});
searchParams = [...searchParams, ...asc, ...desc];
const queryString = searchParams.join("&");
- console.log(queryString);
+ tracer.startSpan('getDataQueryString').addEvent('queryString', { queryString });
let address = apiList.jobs;
if (queryString !== "") {
address = `${address}?${queryString}`;
}
- console.log(address);
+ tracer.startSpan('getDataAddress').addEvent('address', { address });
axios
.get(address, {
headers: {
@@ -772,11 +797,11 @@ const MyJobs = (props) => {
},
})
.then((response) => {
- console.log(response.data);
+ tracer.startSpan('getDataSuccess').addEvent('response', { response: response.data });
setJobs(response.data);
})
.catch((err) => {
- console.log(err.response.data);
+ tracer.startSpan('getDataError').addEvent('error', { error: err.response.data });
setPopup({
open: true,
severity: "error",
@@ -808,12 +833,13 @@ const MyJobs = (props) => {
+ onChange={(event) => {
+ tracer.startSpan('searchQueryChange').addEvent('query', { query: event.target.value });
setSearchOptions({
...searchOptions,
query: event.target.value,
- })
- }
+ });
+ }}
onKeyPress={(ev) => {
if (ev.key === "Enter") {
getData();
diff --git a/frontend/src/component/recruiter/Profile.js b/frontend/src/component/recruiter/Profile.js
index ab42023..eccd743 100644
--- a/frontend/src/component/recruiter/Profile.js
+++ b/frontend/src/component/recruiter/Profile.js
@@ -16,6 +16,8 @@ import { SetPopupContext } from "../../App";
import apiList from "../../lib/apiList";
+import { diag } from '@opentelemetry/api';
+
const useStyles = makeStyles((theme) => ({
body: {
height: "inherit",
@@ -42,6 +44,7 @@ const Profile = (props) => {
const [phone, setPhone] = useState("");
const handleInput = (key, value) => {
+ diag.debug(`Updating profileDetails: key=${key}, value=${value}`);
setProfileDetails({
...profileDetails,
[key]: value,
@@ -49,10 +52,12 @@ const Profile = (props) => {
};
useEffect(() => {
+ diag.debug('Component mounted, calling getData');
getData();
}, []);
const getData = () => {
+ diag.debug('Fetching user data from API');
axios
.get(apiList.user, {
headers: {
@@ -60,12 +65,12 @@ const Profile = (props) => {
},
})
.then((response) => {
- console.log(response.data);
+ diag.debug(`Received user data: ${JSON.stringify(response.data)}`);
setProfileDetails(response.data);
setPhone(response.data.contactNumber);
})
.catch((err) => {
- console.log(err.response.data);
+ diag.error(`Error fetching user data: ${err.response.data}`);
setPopup({
open: true,
severity: "error",
@@ -75,6 +80,7 @@ const Profile = (props) => {
};
const handleUpdate = () => {
+ diag.debug('Updating user profile');
let updatedDetails = {
...profileDetails,
};
@@ -90,6 +96,7 @@ const Profile = (props) => {
};
}
+ diag.debug(`Sending updated details to API: ${JSON.stringify(updatedDetails)}`);
axios
.put(apiList.user, updatedDetails, {
headers: {
@@ -97,6 +104,7 @@ const Profile = (props) => {
},
})
.then((response) => {
+ diag.debug(`Profile updated successfully: ${response.data.message}`);
setPopup({
open: true,
severity: "success",
@@ -105,12 +113,12 @@ const Profile = (props) => {
getData();
})
.catch((err) => {
+ diag.error(`Error updating profile: ${err.response.data.message}`);
setPopup({
open: true,
severity: "error",
message: err.response.data.message,
});
- console.log(err.response);
});
};
diff --git a/frontend/src/index.js b/frontend/src/index.js
index ef2edf8..794d1e0 100644
--- a/frontend/src/index.js
+++ b/frontend/src/index.js
@@ -3,7 +3,9 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
+import { diag } from '@opentelemetry/api';
+diag.info('Rendering React application');
ReactDOM.render(
@@ -11,7 +13,5 @@ ReactDOM.render(
document.getElementById('root')
);
-// If you want to start measuring performance in your app, pass a function
-// to log results (for example: reportWebVitals(console.log))
-// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
+diag.info('Calling reportWebVitals');
reportWebVitals();
diff --git a/frontend/src/lib/EmailInput.js b/frontend/src/lib/EmailInput.js
index deba1a6..d1a26fa 100644
--- a/frontend/src/lib/EmailInput.js
+++ b/frontend/src/lib/EmailInput.js
@@ -1,4 +1,5 @@
import { TextField } from "@material-ui/core";
+import { diag } from '@opentelemetry/api';
const EmailInput = (props) => {
const {
@@ -11,6 +12,8 @@ const EmailInput = (props) => {
className,
} = props;
+ diag.debug('EmailInput props', { label, value, required, className });
+
return (
{
onChange={onChange}
helperText={inputErrorHandler.email.message}
onBlur={(event) => {
+ diag.debug('onBlur event triggered', { value: event.target.value });
if (event.target.value === "") {
+ diag.debug('Input value is empty');
if (required) {
+ diag.debug('Email is required');
handleInputError("email", true, "Email is required");
} else {
+ diag.debug('Email is not required');
handleInputError("email", false, "");
}
} else {
const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+ diag.debug('Regex for email validation', { regex: re });
if (re.test(String(event.target.value).toLowerCase())) {
+ diag.debug('Email format is correct');
handleInputError("email", false, "");
} else {
+ diag.debug('Email format is incorrect');
handleInputError("email", true, "Incorrect email format");
}
}
diff --git a/frontend/src/lib/FileUploadInput.js b/frontend/src/lib/FileUploadInput.js
index d564926..1ee1b5a 100644
--- a/frontend/src/lib/FileUploadInput.js
+++ b/frontend/src/lib/FileUploadInput.js
@@ -2,6 +2,7 @@ import { useState, useContext } from "react";
import { Grid, Button, TextField, LinearProgress } from "@material-ui/core";
import { CloudUpload } from "@material-ui/icons";
import Axios from "axios";
+import { diag } from '@opentelemetry/api';
import { SetPopupContext } from "../App";
@@ -14,7 +15,7 @@ const FileUploadInput = (props) => {
const [uploadPercentage, setUploadPercentage] = useState(0);
const handleUpload = () => {
- console.log(file);
+ diag.debug('File to be uploaded:', file);
const data = new FormData();
data.append("file", file);
Axios.post(uploadTo, data, {
@@ -22,15 +23,15 @@ const FileUploadInput = (props) => {
"Content-Type": "multipart/form-data",
},
onUploadProgress: (progressEvent) => {
- setUploadPercentage(
- parseInt(
- Math.round((progressEvent.loaded * 100) / progressEvent.total)
- )
+ const percentage = parseInt(
+ Math.round((progressEvent.loaded * 100) / progressEvent.total)
);
+ diag.debug('Upload progress:', percentage);
+ setUploadPercentage(percentage);
},
})
.then((response) => {
- console.log(response.data);
+ diag.debug('Upload response data:', response.data);
handleInput(identifier, response.data.url);
setPopup({
open: true,
@@ -39,7 +40,7 @@ const FileUploadInput = (props) => {
});
})
.catch((err) => {
- console.log(err.response);
+ diag.debug('Upload error response:', err.response);
setPopup({
open: true,
severity: "error",
@@ -66,7 +67,7 @@ const FileUploadInput = (props) => {
type="file"
style={{ display: "none" }}
onChange={(event) => {
- console.log(event.target.files);
+ diag.debug('Selected file:', event.target.files[0]);
setUploadPercentage(0);
setFile(event.target.files[0]);
}}
diff --git a/frontend/src/lib/MessagePopup.js b/frontend/src/lib/MessagePopup.js
index cab6b30..93ce8b5 100644
--- a/frontend/src/lib/MessagePopup.js
+++ b/frontend/src/lib/MessagePopup.js
@@ -1,13 +1,18 @@
import { Snackbar, Slide } from "@material-ui/core";
import { Alert } from "@material-ui/lab";
+import { diag } from '@opentelemetry/api';
const MessagePopup = (props) => {
const handleClose = (event, reason) => {
+ diag.debug('handleClose called with reason:', reason);
if (reason === "clickaway") {
+ diag.debug('handleClose early return due to clickaway');
return;
}
+ diag.debug('Setting props.setOpen to false');
props.setOpen(false);
};
+ diag.debug('Rendering Snackbar with props:', props);
return (
diff --git a/frontend/src/lib/PasswordInput.js b/frontend/src/lib/PasswordInput.js
index 00c97d3..aa06965 100644
--- a/frontend/src/lib/PasswordInput.js
+++ b/frontend/src/lib/PasswordInput.js
@@ -1,4 +1,5 @@
import { useState } from "react";
+import { diag } from '@opentelemetry/api';
import {
FormControl,
InputLabel,
@@ -12,13 +13,16 @@ import VisibilityOff from "@material-ui/icons/VisibilityOff";
const PasswordInput = (props) => {
const [showPassword, setShowPassword] = useState(false);
+ diag.debug('Initial showPassword state: ', showPassword);
const handleShowPassword = () => {
setShowPassword(!showPassword);
+ diag.debug('Toggled showPassword state: ', !showPassword);
};
const handleMouseDownPassword = (event) => {
event.preventDefault();
+ diag.debug('Mouse down event prevented on password input');
};
return (
@@ -42,7 +46,10 @@ const PasswordInput = (props) => {
}
value={props.value}
- onChange={(event) => props.onChange(event)}
+ onChange={(event) => {
+ diag.debug('Password input value changed: ', event.target.value);
+ props.onChange(event);
+ }}
labelWidth={props.labelWidth ? props.labelWidth : 70}
className={props.className}
onBlur={props.onBlur ? props.onBlur : null}
diff --git a/frontend/src/lib/apiList.js b/frontend/src/lib/apiList.js
index f2eb26b..e2bd7c3 100644
--- a/frontend/src/lib/apiList.js
+++ b/frontend/src/lib/apiList.js
@@ -1,4 +1,7 @@
+import { diag } from '@opentelemetry/api';
+
export const server = "http://localhost:4444";
+diag.debug(`Server URL: ${server}`);
const apiList = {
login: `${server}/auth/login`,
@@ -12,4 +15,6 @@ const apiList = {
applicants: `${server}/api/applicants`,
};
+diag.debug(`API List: ${JSON.stringify(apiList)}`);
+
export default apiList;
diff --git a/frontend/src/lib/isAuth.js b/frontend/src/lib/isAuth.js
index 1684d2f..ae95c8e 100644
--- a/frontend/src/lib/isAuth.js
+++ b/frontend/src/lib/isAuth.js
@@ -1,9 +1,15 @@
+import { diag } from '@opentelemetry/api';
+
const isAuth = () => {
- return localStorage.getItem("token");
+ const token = localStorage.getItem("token");
+ diag.debug('Retrieved token from localStorage', { token });
+ return token;
};
export const userType = () => {
- return localStorage.getItem("type");
+ const type = localStorage.getItem("type");
+ diag.debug('Retrieved user type from localStorage', { type });
+ return type;
};
export default isAuth;
diff --git a/frontend/src/reportWebVitals.js b/frontend/src/reportWebVitals.js
index 5253d3a..7fc1848 100644
--- a/frontend/src/reportWebVitals.js
+++ b/frontend/src/reportWebVitals.js
@@ -1,12 +1,24 @@
+const { diag } = require('@opentelemetry/api');
+
const reportWebVitals = onPerfEntry => {
+ diag.debug('reportWebVitals function called with onPerfEntry:', onPerfEntry);
if (onPerfEntry && onPerfEntry instanceof Function) {
+ diag.debug('onPerfEntry is a function, proceeding to import web-vitals');
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+ diag.debug('web-vitals module imported successfully');
+ diag.debug('Calling getCLS with onPerfEntry');
getCLS(onPerfEntry);
+ diag.debug('Calling getFID with onPerfEntry');
getFID(onPerfEntry);
+ diag.debug('Calling getFCP with onPerfEntry');
getFCP(onPerfEntry);
+ diag.debug('Calling getLCP with onPerfEntry');
getLCP(onPerfEntry);
+ diag.debug('Calling getTTFB with onPerfEntry');
getTTFB(onPerfEntry);
});
+ } else {
+ diag.debug('onPerfEntry is not a function or is undefined');
}
};
diff --git a/frontend/src/setupTests.js b/frontend/src/setupTests.js
index 8f2609b..613d03f 100644
--- a/frontend/src/setupTests.js
+++ b/frontend/src/setupTests.js
@@ -1,5 +1,10 @@
+```javascript
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';
+import { diag } from '@opentelemetry/api';
+
+diag.info('jest-dom has been imported for custom jest matchers.');
+```