当前位置: 首页 > news >正文

免费vip电影网站怎么做松江专业做网站公司

免费vip电影网站怎么做,松江专业做网站公司,深圳网站开发哪家公司好,万网网站购买为什么服务器要有一个日志系统#xff1f; 故障排查和调试#xff1a; 在服务器运行期间#xff0c;可能会发生各种问题和故障#xff0c;例如程序崩溃、性能下降、异常请求等。日志记录了服务器的运行状态、错误信息和各种操作#xff0c;这些日志可以用来快速定位和排查…为什么服务器要有一个日志系统 故障排查和调试 在服务器运行期间可能会发生各种问题和故障例如程序崩溃、性能下降、异常请求等。日志记录了服务器的运行状态、错误信息和各种操作这些日志可以用来快速定位和排查问题帮助开发人员更容易地找到问题的根本原因从而更快地修复bug和提高服务器稳定性。 性能监测 通过日志系统可以记录服务器的性能数据包括请求处理时间、吞吐量、内存使用情况、CPU利用率等等。这些数据有助于监控服务器的性能发现潜在的性能瓶颈以便进行性能优化。 安全性 日志可以记录系统的安全事件如登录失败尝试、异常访问等。通过分析这些日志可以检测和防止潜在的安全威胁提高服务器的安全性。 法律合规性 某些行业和法规要求服务器必须记录和保留特定类型的操作日志以便进行审计和合规性检查。缺乏合规性的日志记录可能会导致法律责任。 运营和分析 运营团队可以通过分析日志数据来了解用户行为、产品使用情况和趋势。这有助于改进产品、优化用户体验和制定业务策略。 历史记录 日志还可以用作历史记录以跟踪系统的状态和操作历史。这对于了解系统的演化和历史情况非常有用。 实现过程 为了实现异步写入利用循环数组实现阻塞队列。 template class T class block_queue { public:block_queue(int max_size 1000){if (max_size 0){exit(-1);}m_max_size max_size;m_array new T[max_size];m_size 0;m_front -1;m_back -1;}void clear(){m_mutex.lock();m_size 0;m_front -1;m_back -1;m_mutex.unlock();}~block_queue(){m_mutex.lock();if (m_array ! NULL)delete [] m_array;m_mutex.unlock();}//判断队列是否满了bool full() {m_mutex.lock();if (m_size m_max_size){m_mutex.unlock();return true;}m_mutex.unlock();return false;}//判断队列是否为空bool empty() {m_mutex.lock();if (0 m_size){m_mutex.unlock();return true;}m_mutex.unlock();return false;}//返回队首元素bool front(T value) {m_mutex.lock();if (0 m_size){m_mutex.unlock();return false;}value m_array[m_front];m_mutex.unlock();return true;}//返回队尾元素bool back(T value) {m_mutex.lock();if (0 m_size){m_mutex.unlock();return false;}value m_array[m_back];m_mutex.unlock();return true;}int size() {int tmp 0;m_mutex.lock();tmp m_size;m_mutex.unlock();return tmp;}int max_size(){int tmp 0;m_mutex.lock();tmp m_max_size;m_mutex.unlock();return tmp;}//往队列添加元素需要将所有使用队列的线程先唤醒//当有元素push进队列,相当于生产者生产了一个元素//若当前没有线程等待条件变量,则唤醒无意义bool push(const T item){m_mutex.lock();if (m_size m_max_size){m_cond.broadcast();m_mutex.unlock();return false;}m_back (m_back 1) % m_max_size;m_array[m_back] item;m_size;m_cond.broadcast();m_mutex.unlock();return true;}//pop时,如果当前队列没有元素,将会等待条件变量bool pop(T item){m_mutex.lock();while (m_size 0){if (!m_cond.wait(m_mutex.get())){m_mutex.unlock();return false;}}/*m_front (m_front 1) % m_max_size;item m_array[m_front];*///这里我认为应该先得到值然后更新m_front下标itemm_array[m_front];m_front(m_frong1)% m_max_size;m_size--;m_mutex.unlock();return true;}//增加了超时处理bool pop(T item, int ms_timeout){struct timespec t {0, 0};struct timeval now {0, 0};gettimeofday(now, NULL);m_mutex.lock();if (m_size 0){t.tv_sec now.tv_sec ms_timeout / 1000;t.tv_nsec (ms_timeout % 1000) * 1000;if (!m_cond.timewait(m_mutex.get(), t)){m_mutex.unlock();return false;}}if (m_size 0){m_mutex.unlock();return false;}m_front (m_front 1) % m_max_size;item m_array[m_front];m_size--;m_mutex.unlock();return true;}private:locker m_mutex; //互斥锁cond m_cond; //条件变量T *m_array; //存放日志的数组int m_size; //已经用的空间int m_max_size; //最大容量int m_front; //数组头的下标int m_back; //数组尾的下标 }; 解释下timespec结构体和timeval结构体timespec结构体分为秒和微秒两个部分timeval结构体now分为秒和纳秒两个部分。在这个自定义队列中当队列为空时从队列中获取元素的线程将会被挂起当队列是满时往队列里添加元素的线程将会挂起。 class Log { public://C11以后,使用局部变量懒汉不用加锁static Log *get_instance(){static Log instance;return instance;}static void *flush_log_thread(void *args){Log::get_instance()-async_write_log();}//可选择的参数有日志文件、日志缓冲区大小、最大行数以及最长日志条队列bool init(const char *file_name, int close_log, int log_buf_size 8192, int split_lines 5000000, int max_queue_size 0);void write_log(int level, const char *format, ...);void flush(void);private:Log();virtual ~Log();void *async_write_log(){string single_log;//从阻塞队列中取出一个日志string写入文件while (m_log_queue-pop(single_log)){m_mutex.lock();fputs(single_log.c_str(), m_fp);m_mutex.unlock();}}private:char dir_name[128]; //路径名char log_name[128]; //log文件名int m_split_lines; //日志最大行数int m_log_buf_size; //日志缓冲区大小long long m_count; //日志行数记录int m_today; //因为按天分类,记录当前时间是那一天FILE *m_fp; //打开log的文件指针char *m_buf; //缓冲区block_queuestring *m_log_queue; //阻塞队列bool m_is_async; //是否同步标志位locker m_mutex; //互斥锁int m_close_log; //关闭日志 };#define LOG_DEBUG(format, ...) if(0 m_close_log) {Log::get_instance()-write_log(0, format, ##__VA_ARGS__); Log::get_instance()-flush();} #define LOG_INFO(format, ...) if(0 m_close_log) {Log::get_instance()-write_log(1, format, ##__VA_ARGS__); Log::get_instance()-flush();} #define LOG_WARN(format, ...) if(0 m_close_log) {Log::get_instance()-write_log(2, format, ##__VA_ARGS__); Log::get_instance()-flush();} #define LOG_ERROR(format, ...) if(0 m_close_log) {Log::get_instance()-write_log(3, format, ##__VA_ARGS__); Log::get_instance()-flush();} 本项目中使用单例模式创建日志系统记录服务器的运行状态、错误信息和访问数据。能够按天分类超行分类。可以选择同步和异步写入两种方式。 同步打开对应的文件写入日志异步则采取生产者-消费者模型封装为阻塞队列创建一个写线程工作线程将要写的日志push进队列写线程从队列中读取内容写入日志。 在这个项目的日志系统中如果设置了阻塞队列的长度则代表选择了异步写入日志如果没有设置则代表同步写入日志。 为什么要日志分级 信息过滤 在大型应用程序中产生的日志可能非常庞大。通过分级可以根据需要选择性地查看日志。例如开发人员可能只对错误和警告感兴趣而不关心调试信息。 故障排查 当应用程序出现故障或错误时日志分级可以帮助开发人员快速定位问题。错误日志可以提供关于发生了什么错误的详细信息而调试日志则可以提供更多上下文帮助解决问题。 性能监测 分级日志还可以用于监测应用程序的性能。通过记录某些操作的耗时信息开发人员可以识别性能瓶颈并进行优化。 审核和合规性 在某些情况下应用程序需要记录特定事件或行为以满足合规性要求或进行审核。通过使用不同级别的日志可以轻松地识别和检索这些信息。 容易维护 通过使用分级日志开发人员可以更容易地维护应用程序的日志记录。不同级别的日志通常被写入不同的文件或存储位置这使得查找和清理日志变得更加简单。 常见的日志级别包括 DEBUG调试 用于记录详细的调试信息通常只在开发和测试阶段启用。 INFO信息 用于记录应用程序的重要事件和状态信息例如启动、关闭、用户登录等。 WARNING警告 用于记录可能需要关注但不一定是错误的事件例如配置警告或不寻常的操作。 ERROR错误 用于记录应用程序的错误事件例如异常、未处理的异常、无法连接到数据库等。 CRITICAL关键 用于记录严重错误可能导致应用程序无法正常运行的情况例如关键服务崩溃。 本项目中包括DEBUG,INFO,WARN,ERROR四个级别。 #define LOG_DEBUG(format, ...) Log::get_instance()-write_log(0, format, __VA_ARGS__) #define LOG_INFO(format, ...) Log::get_instance()-write_log(1, format, __VA_ARGS__) #define LOG_WARN(format, ...) Log::get_instance()-write_log(2, format, __VA_ARGS__) #define LOG_ERROR(format, ...) Log::get_instance()-write_log(3, format, __VA_ARGS__) 在init函数中完成路径名文件名等私有数据成员的设置。 if (p NULL) {snprintf(log_full_name, 255, %d_%02d_%02d_%s, my_tm.tm_year 1900, my_tm.tm_mon 1, my_tm.tm_mday, file_name); } else {strcpy(log_name, p 1);strncpy(dir_name, file_name, p - file_name 1);snprintf(log_full_name, 255, %s%d_%02d_%02d_%s, dir_name, my_tm.tm_year 1900, my_tm.tm_mon 1, my_tm.tm_mday, log_name); } 这段代码判断file_name是是否包含\如果不包含也就是没有包含路径信息那么就用当前日期和file_name来构建日志文件名。p为空则代表file_name不包含路径信息只包含文件名那么生成最终文件名:年_月_日_文件名。如果p不为空那么找到最后一个路径分隔符计算出文件名所在文件夹的长度并将路径复制到dir_name中文件名复制到log_name中最终构建的路径是文件路径时间文件名。也就是根据是否包含路径信息生成不同格式的日志文件名。 接下来是分级和分片函数 void Log::write_log(int level, const char *format, ...) {struct timeval now {0, 0};gettimeofday(now, NULL);time_t t now.tv_sec;struct tm *sys_tm localtime(t);struct tm my_tm *sys_tm;char s[16] {0};switch (level){case 0:strcpy(s, [debug]:);break;case 1:strcpy(s, [info]:);break;case 2:strcpy(s, [warn]:);break;case 3:strcpy(s, [erro]:);break;default:strcpy(s, [info]:);break;}//写入一个log对m_count, m_split_lines最大行数m_mutex.lock();m_count;if (m_today ! my_tm.tm_mday || m_count % m_split_lines 0) //everyday log{char new_log[256] {0};fflush(m_fp);fclose(m_fp);char tail[16] {0};snprintf(tail, 16, %d_%02d_%02d_, my_tm.tm_year 1900, my_tm.tm_mon 1, my_tm.tm_mday);if (m_today ! my_tm.tm_mday){snprintf(new_log, 255, %s%s%s, dir_name, tail, log_name);m_today my_tm.tm_mday;m_count 0;}else{snprintf(new_log, 255, %s%s%s.%lld, dir_name, tail, log_name, m_count / m_split_lines);}m_fp fopen(new_log, a);}m_mutex.unlock();va_list valst;va_start(valst, format);string log_str;m_mutex.lock();//写入的具体时间内容格式int n snprintf(m_buf, 48, %d-%02d-%02d %02d:%02d:%02d.%06ld %s ,my_tm.tm_year 1900, my_tm.tm_mon 1, my_tm.tm_mday,my_tm.tm_hour, my_tm.tm_min, my_tm.tm_sec, now.tv_usec, s);int m vsnprintf(m_buf n, m_log_buf_size - n - 1, format, valst);m_buf[n m] \n;m_buf[n m 1] \0;log_str m_buf;m_mutex.unlock();if (m_is_async !m_log_queue-full()){m_log_queue-push(log_str);}else{m_mutex.lock();fputs(log_str.c_str(), m_fp);m_mutex.unlock();}va_end(valst); } 思路如下 1、获得今天的日期时间如果日志的日期不是今天则创建新的日志文件然后向新的文件写入。 2、如果是今天的日期时间但是超过了文件的最大行那么就进行分片在文件结尾加入分片的ID比如***_log_file1,***_log_file2这样。然后写入文件。 3、如果是今天的日期并且没有超过最大文件行就写入对应的文件。 准备好要写入的文件后格式化时间和内容放到缓冲数组中然后判断日志系统是异步写入还是同步写入如果是异步则将需要写的日志内容加入到阻塞队列中否则直接调用fputs函数将输入文件指针对应的文件中。
http://www.tj-hxxt.cn/news/231490.html

相关文章:

  • 建设网站需要什么网站设计制作 一年价格
  • 做网站的客户资料交换qq群网站建设太仓
  • 什么叫静态网站帮忙建站的公司
  • 镇江建设银行网站彩票网站的建设
  • 超星网站开发实战答案河北网站建设中心
  • 网站站点多少钱网络设计案例题
  • 网站建设 中关村做网站大概费用
  • 天地做网站网站开发制作公司名称
  • 天津做不锈钢的网站中国网站设计师联盟
  • 在线ps网站怎么让关键词快速排名首页
  • vps网站压缩建设企业网站的时间
  • 规避电子政务门户网站建设的教训卢松松wordpress博客
  • ps怎么做网站一站式服务大厅
  • 营销型 展示类网站企业形象网站策划方案
  • dw做网站首页怎么做手机制作
  • 建设网站模板南京设计网页公司
  • 弹幕网站用什么做通化好的网站建设的公司
  • 亚马逊备案网站建设网站建设包括两个方面
  • 1元购网站怎么做网站建设及推广培训班
  • 怎么样再自己的网站做二级域名wordpress怎么加幻灯片
  • 创新创业营销策略网站建设等wordpress模板自适应
  • 搜索网站怎么做dw个人网站模板下载
  • 中国知名网站排行榜ueditor wordpress 插件
  • 网站开发的关键技术与难点西安app制作公司
  • 网站建设 别墅经常用表格进行页面布局
  • 昆明市建设局官方网站贵阳网站建设哪家
  • 网站建设视频百度网盘下载江苏建设工程信息网官网入口
  • 罗湖网站建设设计精仿36氪(36kr)wordpress主题
  • 摄影网站开发背景asp php jsp网站开发
  • 杭州俄语网站建设wordpress怎么改登陆不了