SQL Server自动化运维系列 - 监控磁盘剩余空间及SQL Server错误日志(Power Shell)
需求描述
在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等。如果发生异常,需要提前预警的,通知形式一般为发邮件告知。
在所有的自检流程中最基础的一个就是磁盘剩余空间检测。作为一个高效的DBA不可能每天都要上生产机上查看磁盘剩余或者直到磁盘无剩余空间报错后才采取扩容措施。
当然,作为微软的服务器有着自己的监控软件:SCCM(System Center Configuration Manager)。但本篇就介绍如果通过Power shell实现状态值监控,相比SCCM更轻量级和更具灵活性。
本篇实现
1、每天检测磁盘剩余空间大小,如果剩余空间超过了阀值,则发邮件告诉管理员
2、每天检测SQL Server运行的错误日志(Window平台的错误日志),形成邮件附件发送给管理员
监控脚本
首先我们来解决第一个问题,关于磁盘剩余空间的问题,对于磁盘的监控的存在两个需要解决的问题:
<1>一般监控我们需要监控很多台服务器的磁盘,所以对于服务器的量控制我们需要生成一个配置文件。
- <computernames>
- <computername>
- wuxuelei-pc
- </computername>
- </computernames>
配置文件名字:computername.xml,这样就解决很多服务器的问题,只需要在配置文件中增加就可以,因为我在本地测试,所以就配置了我的本地电脑
<2>对于服务器的磁盘监控也需要定义一个阀值,用来动态改变,用来定义生成预警的阀值。简单点就是定义我们检测的磁盘剩余空间到了多少了就自动发邮件提醒。
- <Counters>
- <Counter alter = "10" operator = "gt" >C:</Counter>
- <Counter alter = "10" operator = "gt" >D:</Counter>
- <Counter alter = "10" operator = "gt" >E:</Counter>
- <Counter alter = "10" operator = "gt" >F:</Counter>
- </Counters>
文件名为:alter_disk.xml,我定义了四个盘符:C: D: E: F:
当以上四个盘符那个盘符少于10G了就生成邮件预警。
实现代码如下:

- $server = "(local)"
- $uid = "sa"
- $db="master"
- $pwd="password"
- $mailprfname = "TestMail"
- $recipients = "787449667@qq.com"
- $subject = "老大,快去看看这个服务器的磁盘空间马上就不够了!"
- $computernamexml = "F:\PowerShell\发送邮件\computername.xml"
- $alter_xml = "F:\PowerShell\发送邮件\alter_disk.xml"
- function GetServerName($xmlpath)
- {
- $xml = [xml] (Get-Content $xmlpath)
- $return = New-Object Collections.Generic.List[string]
- for($i = 0;$i -lt $xml.computernames.ChildNodes.Count;$i++)
- {
- if ( $xml.computernames.ChildNodes.Count -eq 1)
- {
- $cp = [string]$xml.computernames.computername
- }
- else
- {
- $cp = [string]$xml.computernames.computername[$i]
- }
- $return.Add($cp.Trim())
- }
- $return
- }
- function GetAlterCounter($xmlpath)
- {
- $xml = [xml] (Get-Content $xmlpath)
- $return = New-Object Collections.Generic.List[string]
- $list = $xml.counters.Counter
- $list
- }
- function CreateAlter($message)
- {
- $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
- $CnnString ="Server = $server; Database = $db;User Id = $uid; Password = $pwd"
- $SqlConnection.ConnectionString = $CnnString
- $CC = $SqlConnection.CreateCommand();
- if (-not ($SqlConnection.State -like "Open")) { $SqlConnection.Open() }
- $cc.CommandText=
- " EXEC msdb..sp_send_dbmail
- @profile_name = '$mailprfname'
- ,@recipients = '$recipients'
- ,@body = '$message'
- ,@subject = '$subject'
- "
- $cc.ExecuteNonQuery()|out-null
- $SqlConnection.Close();
- }
- $names = GetServerName($computernamexml)
- $pfcounters = GetAlterCounter($alter_xml)
- foreach($cp in $names)
- {
- $p = New-Object Collections.Generic.List[string]
- $report = ""
- foreach ($pfc in $pfcounters)
- {
- $b = ""
- $counter ="\\"+$cp+"\LogicalDisk("+$pfc.get_InnerText().Trim()+")\% Free Space"
- $p.Add($counter)
- }
- $count = Get-Counter $p
- #Write-Host $count.CounterSamples.Count;
- for ($i = 0; $i -lt $count.CounterSamples.Count; $i++)
- {
- $v = $count.CounterSamples.Get($i).CookedValue
- $pfc = $pfcounters[$i]
- #$pfc.get_InnerText()
- $b = ""
- $lg = ""
- if ($pfc.operator -eq "gt")
- {
- if( $v -le [double]$pfc.alter)
- {
- $b = "alter"
- $lg = "Less Than"
- }
- if($b -eq "alter")
- {
- $path = "机器名:"+$cp+"; 盘符:"+$pfc.get_InnerText()
- $diskFree="; 当前剩余空间为:"+[math]::truncate($v).ToString()+"G;"
- $aler=" 超过了你预定的阀值:"+$pfc.alter.Trim()+"G;速度去处理吧!"
- $item = "{0} {1} {2}" -f $path,$diskFree,$aler
- $report += $item + "`n"
- }
- }
- }
- if($report -ne "")
- {
- #生产警告 参数 计数器,阀值,当前值
- CreateAlter $report
- }
- }

通过如上脚本,生成跑批任务,就可以自动的检测磁盘剩余空间了,而不需要我们去手动检测了。
上述代码中,有两个技术点:1、需要自己配置SQL Server邮件代理;2、需要自己配置跑批计划,方法自己网上搜,很简单。
效果图如下
嘿...看到上面的邮件,就是需要联系硬件架构师,让其扩容或者清除冗余数据的时候了。
在上面的脚本中,的确只有我的F盘符超了阀值,所以警报了!
其次,我们来解决第二个问题,关于SQL Server错误日志的问题,作为日常的DBA管理系统中,查看SQL Server错误日志是一种常用的方式。当然,如果系统运行正常,不会产生错误日志,一单出现问题,就会生成错误日志,但是对于SQL Server错误日志会产生很多条,为了方便查找,我们会让其生成一个文本文件。
以邮件附件的形式,告知管理员,然后管理员就可以通过日志文件快速的定位问题的源头。
同样,本篇也是通过computername.xml文件,对多台服务器进行错误日志进行筛选
脚本很简单,如下

- $server = "(local)"
- $uid = "sa"
- $db="master"
- $pwd="password"
- $mailprfname = "TestMail"
- $recipients = "787449667@qq.com"
- $subject = "老大,快去看看这个服务器的SQL Server出问题了!"
- $Info="附件为SQL Server错误日志....."
- $computernamexml = "F:\PowerShell\发送邮件\computername.xml"
- function GetServerName($xmlpath)
- {
- $xml = [xml] (Get-Content $xmlpath)
- $return = New-Object Collections.Generic.List[string]
- for($i = 0;$i -lt $xml.computernames.ChildNodes.Count;$i++)
- {
- if ( $xml.computernames.ChildNodes.Count -eq 1)
- {
- $cp = [string]$xml.computernames.computername
- }
- else
- {
- $cp = [string]$xml.computernames.computername[$i]
- }
- $return.Add($cp.Trim())
- }
- $return
- }
- function GetAlterCounter($xmlpath)
- {
- $xml = [xml] (Get-Content $xmlpath)
- $return = New-Object Collections.Generic.List[string]
- $list = $xml.counters.Counter
- $list
- }
- function CreateAlter($message)
- {
- $SqlConnection = New-Object System.Data.SqlClient.SqlConnection
- $CnnString ="Server = $server; Database = $db;User Id = $uid; Password = $pwd"
- $SqlConnection.ConnectionString = $CnnString
- $CC = $SqlConnection.CreateCommand();
- if (-not ($SqlConnection.State -like "Open")) { $SqlConnection.Open() }
- $cc.CommandText=
- " EXEC msdb..sp_send_dbmail
- @profile_name = '$mailprfname'
- ,@recipients = '$recipients'
- ,@body = '$Info'
- ,@subject = '$subject'
- ,@file_attachments='$message'
- "
- $cc.ExecuteNonQuery()|out-null
- $SqlConnection.Close();
- }
- $names = GetServerName($computernamexml)
- foreach($cp in $names)
- {
- #输出系统日志中某个特定程序的日志到文件,比如SQL Server,然后选择错误类型为Error
- Get-EventLog -ComputerName $cp application | where-object{$_.source-like "MSSQLSERVER"} | where-object{$_.entryType -eq "error"} >F:\PowerShell\$cp+"SQLErrLog.txt"
- #生产警告 参数 计数器,阀值,当前值
- CreateAlter F:\PowerShell\$cp+"SQLErrLog.txt"
- }

效果图如下
直接下载附件,然后查看错误日志就可以了。
该错误日志还是挺详细的,发生时间,错误明细等
当然,上述脚本还欠缺一点逻辑:
比如:筛选一段时间周期的错误日志、或者只查看上次启动之后的错误日志等。
这些逻辑加上也不麻烦,本身PowerShell实现起来就很简单。这里就不展开了,自己灵活实现。
但是,在我们日常的分析中,在日志记录多的时候,用文本分析的方式还是比较慢,通常用Excel查看效果会好很多。
这个实现也不麻烦,只需要更改脚本如下:

- #输出系统日志中某个特定程序的日志到文件,比如SQL Server,然后选择错误类型为Error
- #Get-EventLog -ComputerName $cp application | where-object{$_.source-like "MSSQLSERVER"} | where-object{$_.entryType -eq "error"} >F:\PowerShell\$cp+"SQLErrLog.txt"
- #输出系统日志中某个特定程序的日志到文件,比如SQL Server,然后选择错误类型为Error,支持Excel打开
- Get-EventLog -ComputerName $cp application | where-object{$_.source-like "MSSQLSERVER"} | where-object{$_.entryType -eq "error"} | Export-Clixml –Path F:\PowerShell\$cp+"SQLErrLog.xml" –Depth 2
- #生产警告 参数 计数器,阀值,当前值
- CreateAlter F:\PowerShell\$cp+"SQLErrLog.xml"

我们下载生成的日志文件,然后打开Excel,然后选择:数据——>从Xml文件导入:
如此分析就方便多了。
结语
本篇就列举了一下利用PowerShell实现自动化运维和检测。算作抛砖引玉了吧,自己另有需求可以自己灵活实现。
关于SQL Server自动化运维和检测的内容很广泛,其中很多都是从日常的经验中出发,一步步的从手动到自动的过程。
后面的文章,我们将会更深入关于SQL Server的自动化优化运维进行分析。有兴趣的童鞋,可以提前关注。
SQL Server自动化运维系列 - 监控磁盘剩余空间及SQL Server错误日志(Power Shell)的更多相关文章
- SQL Server自动化运维系列——监控磁盘剩余空间及SQL Server错误日志(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...
- SQL Server 自动化运维系列 - 监控磁盘剩余空间及SQL Server错误日志(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...
- SQL Server自动化运维系列——监控跑批Job运行状态(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在上一篇文章中已经分析了SQL SERVER中关于邮 ...
- SQL Server自动化运维系列——监控性能指标脚本(Power Shell)
需求描述 一般在生产环境中,有时候需要自动的检测指标值状态,如果发生异常,需要提前预警的,比如发邮件告知,本篇就介绍如果通过Power shell实现状态值监控 监控值范围 根据经验,作为DBA一般需 ...
- SQL Server自动化运维系列——关于邮件通知那点事(.Net开发人员的福利)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 邮件作为一种非常便利的预警实现方式,在及时性和易用性 ...
- SQL Server自动化运维系列——关于数据收集(多服务器数据收集和性能监控)
需求描述 在生产环境中,很多情况下需要采集数据,用以定位问题或者形成基线. 关于SQL Server中的数据采集有着很多种的解决思路,可以采用Trace.Profile.SQLdiag.扩展事件等诸多 ...
- SQL Server自动化运维系列 - 多服务器数据收集和性能监控
需求描述 在生产环境中,很多情况下需要采集数据,用以定位问题或者形成基线. 关于SQL Server中的数据采集有着很多种的解决思路,可以采用Trace.Profile.SQLdiag.扩展事件等诸多 ...
- SQL Server 自动化运维系列 - 多服务器数据收集和性能监控
需求描述 在生产环境中,很多情况下需要采集数据,用以定位问题或者形成基线. 关于SQL Server中的数据采集有着很多种的解决思路,可以采用Trace.Profile.SQLdiag.扩展事件等诸多 ...
- SQL Server自动化运维系列——批量执行SQL脚本(Power Shell)
需求描述 一般在生产环境中,在投产的情况下,需要批量的来执行SQL脚本文件,来完成整个投产,如果投产文件比较多的情况下,无疑这是一个比较痛苦的过程,所以本篇通过PowerShell脚本来批量完成. 监 ...
随机推荐
- Curl之获取外网IP
获取外网IP:curl -s ifconfig.me
- 【转】Kinect使用
文章转自http://blog.csdn.net/yangtrees/article/details/16106271 Kinect中深度值最大为4096mm (0x0fff) 微软建议在开发中使用1 ...
- 多线程模式之MasterWorker模式
多线程模式之MasterWorker模式 Master-Worker模式的核心思想是,系统由两类进程协作工作:Master进程和Worker进程.Master进程负责接收和分配任务,Worker进程负 ...
- JZ2440开发笔记(8)——FCLK、HCLK和PCLK
S3C2440中有三种时钟,分别是FCLK,HCLK和PCLK.这三种时钟的功能各不相同,其中FCLK主要是为ARM920T的内核提供工作频率,如图: HCLK主要是为S3C2440 AHB总线(Ad ...
- bat 批处理 字符串 截取
由于项目中配置项太多,经常有同事在配置xml的时候,讲 配置的路径搞错,先需要搞一个脚本,可以自动将路径截取出来, 晚上收集了点资料,暂时先上几个 bat 后面留着 ,具体实现. @echo off ...
- Codeforces 650C Table Compression (并查集)
题意:M×N的矩阵 让你保持每行每列的大小对应关系不变,将矩阵重写,重写后的最大值最小. 思路:离散化思想+并查集,详见代码 好题! #include <iostream> #includ ...
- strust1.x中formbean的原理及作用
from: http://blog.csdn.net/tuiroger/article/details/3947896 今天张老师讲了一些比较重要的strust标签,<html:link ...
- 《Effect Java》学习笔记1———创建和销毁对象
第二章 创建和销毁对象 1.考虑用静态工厂方法代替构造器 四大优势: i. 有名称 ii. 不必在每次调用它们的时候都创建一个新的对象: iii. 可以返回原返回类型的任何子类型的对象: JDBC ...
- java反射与代理模式
流程age: 饭前洗手----> 吃饭 --->饭后洗碗 //吃饭 public interface Dinner { //吃饭方法 public void haveDinner(); } ...
- IOS开发之tableview只选中一行
场景:一个弹出层,包含一个Tableview,每一行为一个选择条件,且只能选择一个.选中后文体有颜色变化,后面还会有对勾.选择另一个后,前一个恢复成普通状态. 示例代码: -(void)tableVi ...